From 27e3717f7bd5b3900f9250b691a7ea26d5756764 Mon Sep 17 00:00:00 2001 From: Billuc Date: Sun, 17 Nov 2024 19:18:18 +0100 Subject: [PATCH] feat(glitr_convert): Added default_value param to map --- glitr_convert/gleam.toml | 2 +- glitr_convert/src/glitr/convert.gleam | 19 +++++----- glitr_convert/test/converters_test.gleam | 45 +++++++++++++++++------- 3 files changed, 44 insertions(+), 22 deletions(-) diff --git a/glitr_convert/gleam.toml b/glitr_convert/gleam.toml index c0993f6..7aad2f7 100644 --- a/glitr_convert/gleam.toml +++ b/glitr_convert/gleam.toml @@ -1,5 +1,5 @@ name = "glitr_convert" -version = "0.2.2" +version = "0.2.3" # Fill out these fields if you intend to generate HTML documentation or publish # your project to the Hex package manager. diff --git a/glitr_convert/src/glitr/convert.gleam b/glitr_convert/src/glitr/convert.gleam index 0278612..555a0e3 100644 --- a/glitr_convert/src/glitr/convert.gleam +++ b/glitr_convert/src/glitr/convert.gleam @@ -139,13 +139,12 @@ pub fn field( } }, fields_def: { - let converter = next(field_type.default_value) - [#(field_name, field_type.type_def), ..converter.fields_def] - }, - default_value: { - let converter = next(field_type.default_value) - converter.default_value + [ + #(field_name, field_type.type_def), + ..next(field_type.default_value).fields_def + ] }, + default_value: { next(field_type.default_value).default_value }, ) } @@ -469,7 +468,9 @@ pub fn enum( pub fn map( converter: Converter(a), encode_map: fn(b) -> a, - decode_map: fn(a) -> b, + decode_map: fn(a) -> Result(b, List(dynamic.DecodeError)), + default_value: b, + // Kinda required until I find a more elegant way around this ) -> Converter(b) { Converter( fn(v: b) { @@ -478,10 +479,10 @@ pub fn map( }, fn(v: GlitrValue) { converter.decoder(v) - |> result.map(decode_map) + |> result.then(decode_map) }, converter.type_def, - converter.default_value |> decode_map, + default_value, ) } diff --git a/glitr_convert/test/converters_test.gleam b/glitr_convert/test/converters_test.gleam index 87840d5..90f22e4 100644 --- a/glitr_convert/test/converters_test.gleam +++ b/glitr_convert/test/converters_test.gleam @@ -1,6 +1,6 @@ +import gleam/dynamic import gleam/int import gleam/list -import gleam/result import gleam/string import gleeunit/should import glitr/convert @@ -126,6 +126,36 @@ pub type Date { Date(year: Int, month: Int, day: Int) } +fn date_parse(v: String) -> Result(Date, List(dynamic.DecodeError)) { + case string.split(v, "/") { + [y, m, d, ..] -> { + use year <- result_guard(int.parse(y), [ + dynamic.DecodeError("An integer", y, ["year"]), + ]) + use month <- result_guard(int.parse(m), [ + dynamic.DecodeError("An integer", m, ["month"]), + ]) + use day <- result_guard(int.parse(d), [ + dynamic.DecodeError("An integer", d, ["day"]), + ]) + + Ok(Date(year, month, day)) + } + _ -> Error([dynamic.DecodeError("A string of format 'Y/M/D'", v, [])]) + } +} + +fn result_guard( + v: Result(a, _), + otherwise: b, + cb: fn(a) -> Result(c, b), +) -> Result(c, b) { + case v { + Error(_) -> Error(otherwise) + Ok(value) -> cb(value) + } +} + pub fn converter_map_test() { // We are storing the date as a string for optimized memory storage let date_converter = { @@ -134,17 +164,8 @@ pub fn converter_map_test() { fn(v: Date) { [v.year, v.month, v.day] |> list.map(int.to_string) |> string.join("/") }, - fn(v: String) { - let elems = - string.split(v, "/") - |> list.map(fn(el) { int.parse(el) |> result.unwrap(-1) }) - case elems { - [y, m, d, ..] -> Date(y, m, d) - [y, m] -> Date(y, m, -1) - [y] -> Date(y, -1, -1) - [] -> Date(-1, -1, -1) - } - }, + date_parse, + Date(0, 0, 0), ) }