import gleam/dynamic/decode import gleam/json pub type User { User(id: Int, role: Role, full_name: String, email: String) } pub type Role { /// Regular user with default permissions Default /// User with elevated access to the system Admin } pub fn to_json(self: User) -> json.Json { json.object([ #("id", json.int(self.id)), #("role", role_to_json(self.role)), #("full_name", json.string(self.full_name)), #("email", json.string(self.email)), ]) } pub fn decoder() -> decode.Decoder(User) { // How its represented in client-side let decoder_eng = { use id <- decode.field("id", decode.int) use role <- decode.field("role", role_decoder()) use full_name <- decode.field("full_name", decode.string) use email <- decode.field("email", decode.string) decode.success(User(id:, role:, full_name:, email:)) } // How its represented in server-side let decoder_ptbr = { use id <- decode.field("id", decode.int) use full_name <- decode.field("nome", decode.string) use email <- decode.field("email", decode.string) use role <- decode.field("tipo_usuario", role_decoder()) decode.success(User(id:, role:, full_name:, email:)) } decode.one_of(decoder_eng, [decoder_ptbr]) } fn role_to_json(role: Role) -> json.Json { case role { Default -> json.string("default") Admin -> json.string("admin") } } fn role_decoder() -> decode.Decoder(Role) { use variant <- decode.then(decode.string) case variant { "default" | "cliente" -> decode.success(Default) "admin" | "analista" -> decode.success(Admin) _ -> decode.failure(Default, "Role") } }