Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ jobs:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1
with:
otp-version: "26.0.2"
gleam-version: "1.6.1"
otp-version: "27.0.0"
gleam-version: "1.11.1"
rebar3-version: "3"
# elixir-version: "1.15.4"
- run: gleam deps download
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ jobs:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1
with:
otp-version: "26.0.2"
gleam-version: "1.6.1"
otp-version: "27.0.0"
gleam-version: "1.11.1"
rebar3-version: "3"
# elixir-version: "1.15.4"
- run: gleam deps download
Expand Down
2 changes: 1 addition & 1 deletion gleam.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ links = [{ title = "Website", href = "https://hexdocs.pm/convert" }]
# https://gleam.run/writing-gleam/gleam-toml/.

[dependencies]
gleam_stdlib = ">= 0.34.0 and < 2.0.0"
gleam_stdlib = ">= 0.60.0 and < 2.0.0"

[dev-dependencies]
gleeunit = ">= 1.0.0 and < 2.0.0"
6 changes: 3 additions & 3 deletions manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
# You typically do not need to edit this file

packages = [
{ name = "gleam_stdlib", version = "0.45.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "206FCE1A76974AECFC55AEBCD0217D59EDE4E408C016E2CFCCC8FF51278F186E" },
{ name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" },
{ name = "gleam_stdlib", version = "0.60.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "621D600BB134BC239CB2537630899817B1A42E60A1D46C5E9F3FAE39F88C800B" },
{ name = "gleeunit", version = "1.5.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "D33B7736CF0766ED3065F64A1EBB351E72B2E8DE39BAFC8ADA0E35E92A6A934F" },
]

[requirements]
gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" }
gleam_stdlib = { version = ">= 0.60.0 and < 2.0.0" }
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
56 changes: 32 additions & 24 deletions src/convert.gleam
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import gleam/dict
import gleam/dynamic
import gleam/dynamic/decode
import gleam/list
import gleam/option
import gleam/result
Expand Down Expand Up @@ -48,7 +49,7 @@ pub type GlitrValue {
pub opaque type Converter(a) {
Converter(
encoder: fn(a) -> GlitrValue,
decoder: fn(GlitrValue) -> Result(a, List(dynamic.DecodeError)),
decoder: fn(GlitrValue) -> Result(a, List(decode.DecodeError)),
type_def: GlitrType,
// Temporary ugly stuff, while searching for a better solution
default_value: a,
Expand All @@ -59,10 +60,10 @@ pub opaque type Converter(a) {
pub opaque type PartialConverter(base) {
PartialConverter(
encoder: fn(base) -> GlitrValue,
decoder: fn(GlitrValue) -> Result(base, List(dynamic.DecodeError)),
decoder: fn(GlitrValue) -> Result(base, List(decode.DecodeError)),
fields_def: List(#(String, GlitrType)),
// Temporary ugly stuff, while searching for a better solution
default_value: Result(base, List(dynamic.DecodeError)),
default_value: Result(base, List(decode.DecodeError)),
)
}

Expand Down Expand Up @@ -130,7 +131,7 @@ pub fn field(
values
|> list.key_find(field_name)
|> result.replace_error([
dynamic.DecodeError("Value", "None", [field_name]),
decode.DecodeError("Value", "None", [field_name]),
])
|> result.then(field_type.decoder)

Expand Down Expand Up @@ -164,8 +165,7 @@ pub fn string() -> Converter(String) {
fn(v: GlitrValue) {
case v {
StringValue(val) -> Ok(val)
other ->
Error([dynamic.DecodeError("StringValue", get_type(other), [])])
other -> Error([decode.DecodeError("StringValue", get_type(other), [])])
}
},
String,
Expand All @@ -180,7 +180,7 @@ pub fn bool() -> Converter(Bool) {
fn(v: GlitrValue) {
case v {
BoolValue(val) -> Ok(val)
other -> Error([dynamic.DecodeError("BoolValue", get_type(other), [])])
other -> Error([decode.DecodeError("BoolValue", get_type(other), [])])
}
},
Bool,
Expand All @@ -195,7 +195,7 @@ pub fn float() -> Converter(Float) {
fn(v: GlitrValue) {
case v {
FloatValue(val) -> Ok(val)
other -> Error([dynamic.DecodeError("FloatValue", get_type(other), [])])
other -> Error([decode.DecodeError("FloatValue", get_type(other), [])])
}
},
Float,
Expand All @@ -210,7 +210,7 @@ pub fn int() -> Converter(Int) {
fn(v: GlitrValue) {
case v {
IntValue(val) -> Ok(val)
other -> Error([dynamic.DecodeError("IntValue", get_type(other), [])])
other -> Error([decode.DecodeError("IntValue", get_type(other), [])])
}
},
Int,
Expand All @@ -225,7 +225,7 @@ pub fn null() -> Converter(Nil) {
fn(v: GlitrValue) {
case v {
NullValue -> Ok(Nil)
other -> Error([dynamic.DecodeError("NullValue", get_type(other), [])])
other -> Error([decode.DecodeError("NullValue", get_type(other), [])])
}
},
Null,
Expand All @@ -250,7 +250,7 @@ pub fn list(of: Converter(a)) -> Converter(List(a)) {
_, Error(errs) | Error(errs), _ -> Error(errs)
}
})
other -> Error([dynamic.DecodeError("ListValue", get_type(other), [])])
other -> Error([decode.DecodeError("ListValue", get_type(other), [])])
}
},
List(of.type_def),
Expand All @@ -270,7 +270,7 @@ pub fn optional(of: Converter(a)) -> Converter(option.Option(a)) {
OptionalValue(option.Some(val)) ->
val |> of.decoder |> result.map(option.Some)
other ->
Error([dynamic.DecodeError("OptionalValue", get_type(other), [])])
Error([decode.DecodeError("OptionalValue", get_type(other), [])])
}
},
Optional(of.type_def),
Expand All @@ -296,8 +296,7 @@ pub fn result(
case v {
ResultValue(Ok(val)) -> val |> res.decoder |> result.map(Ok)
ResultValue(Error(val)) -> val |> error.decoder |> result.map(Error)
other ->
Error([dynamic.DecodeError("ResultValue", get_type(other), [])])
other -> Error([decode.DecodeError("ResultValue", get_type(other), [])])
}
},
Result(res.type_def, error.type_def),
Expand Down Expand Up @@ -349,7 +348,7 @@ pub fn dict(
}
})
|> result.map(dict.from_list)
other -> Error([dynamic.DecodeError("DictValue", get_type(other), [])])
other -> Error([decode.DecodeError("DictValue", get_type(other), [])])
}
},
Dict(key.type_def, value.type_def),
Expand Down Expand Up @@ -422,7 +421,7 @@ pub fn enum(
converters
|> list.key_find(variant_name)
|> result.replace_error([
dynamic.DecodeError(
decode.DecodeError(
"One of: "
<> converters |> list.map(fn(v) { v.0 }) |> string.join("/"),
variant_name,
Expand All @@ -432,7 +431,7 @@ pub fn enum(
)
variant.decoder(value)
}
other -> Error([dynamic.DecodeError("EnumValue", get_type(other), [])])
other -> Error([decode.DecodeError("EnumValue", get_type(other), [])])
}
},
Enum(converters |> list.map(fn(var) { #(var.0, { var.1 }.type_def) })),
Expand All @@ -451,11 +450,11 @@ pub fn dynamic() -> Converter(dynamic.Dynamic) {
case v {
DynamicValue(val) -> Ok(val)
other ->
Error([dynamic.DecodeError("DynamicValue", get_type(other), [])])
Error([decode.DecodeError("DynamicValue", get_type(other), [])])
}
},
Dynamic,
dynamic.from(Nil),
dynamic.nil(),
)
}

Expand All @@ -467,7 +466,7 @@ pub fn bit_array() -> Converter(BitArray) {
case v {
BitArrayValue(val) -> Ok(val)
other ->
Error([dynamic.DecodeError("BitArrayValue", get_type(other), [])])
Error([decode.DecodeError("BitArrayValue", get_type(other), [])])
}
},
BitArray,
Expand All @@ -493,16 +492,16 @@ pub fn bit_array() -> Converter(BitArray) {
/// case elems {
/// [y, m, d, ..] -> Ok(Date(y, m, d))
/// _ -> Error([])
/// },
/// }
/// }
/// },
/// Date(0, 0, 0) // This is required for now...
/// )
/// }
/// ```
pub fn map(
converter: Converter(a),
encode_map: fn(b) -> a,
decode_map: fn(a) -> Result(b, List(dynamic.DecodeError)),
decode_map: fn(a) -> Result(b, List(decode.DecodeError)),
default_value: b,
// Kinda required until I find a more elegant way around this
) -> Converter(b) {
Expand Down Expand Up @@ -547,11 +546,20 @@ pub fn encode(converter: Converter(a)) -> fn(a) -> GlitrValue {
/// Decode a GlitrValue using the provided converter.
pub fn decode(
converter: Converter(a),
) -> fn(GlitrValue) -> Result(a, List(dynamic.DecodeError)) {
) -> fn(GlitrValue) -> Result(a, List(decode.DecodeError)) {
converter.decoder
}

/// Return the GlitrType associated with the converter
pub fn type_def(converter: Converter(a)) -> GlitrType {
converter.type_def
}

/// Retrieve the default value associated with a converter.
///
/// This value is used as a fallback when decoding fails,
/// especially when building decoders that must return a value
/// even in the presence of errors.
pub fn default_value(conv: Converter(a)) -> a {
conv.default_value
}
12 changes: 6 additions & 6 deletions test/convert_test.gleam
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import convert
import gleam/dynamic
import gleam/dynamic/decode
import gleam/int
import gleam/list
import gleam/string
Expand Down Expand Up @@ -127,22 +127,22 @@ pub type Date {
Date(year: Int, month: Int, day: Int)
}

fn date_parse(v: String) -> Result(Date, List(dynamic.DecodeError)) {
fn date_parse(v: String) -> Result(Date, List(decode.DecodeError)) {
case string.split(v, "/") {
[y, m, d, ..] -> {
use year <- result_guard(int.parse(y), [
dynamic.DecodeError("An integer", y, ["year"]),
decode.DecodeError("An integer", y, ["year"]),
])
use month <- result_guard(int.parse(m), [
dynamic.DecodeError("An integer", m, ["month"]),
decode.DecodeError("An integer", m, ["month"]),
])
use day <- result_guard(int.parse(d), [
dynamic.DecodeError("An integer", d, ["day"]),
decode.DecodeError("An integer", d, ["day"]),
])

Ok(Date(year, month, day))
}
_ -> Error([dynamic.DecodeError("A string of format 'Y/M/D'", v, [])])
_ -> Error([decode.DecodeError("A string of format 'Y/M/D'", v, [])])
}
}

Expand Down