implemented json serde 🦀
This commit is contained in:
parent
5b5fdab050
commit
2202a62604
@ -15,6 +15,9 @@ version = "1.0.0"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
gleam_stdlib = ">= 0.45.0 and < 2.0.0"
|
gleam_stdlib = ">= 0.45.0 and < 2.0.0"
|
||||||
gleam_otp = ">= 0.14.1 and < 1.0.0"
|
gleam_otp = ">= 0.14.1 and < 1.0.0"
|
||||||
|
gleam_json = ">= 2.1.0 and < 3.0.0"
|
||||||
|
simplifile = ">= 2.2.0 and < 3.0.0"
|
||||||
|
decode = ">= 0.5.0 and < 1.0.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
gleeunit = ">= 1.0.0 and < 2.0.0"
|
gleeunit = ">= 1.0.0 and < 2.0.0"
|
||||||
|
|||||||
@ -3,15 +3,22 @@
|
|||||||
|
|
||||||
packages = [
|
packages = [
|
||||||
{ name = "birl", version = "1.7.1", build_tools = ["gleam"], requirements = ["gleam_stdlib", "ranger"], otp_app = "birl", source = "hex", outer_checksum = "5C66647D62BCB11FE327E7A6024907C4A17954EF22865FE0940B54A852446D01" },
|
{ name = "birl", version = "1.7.1", build_tools = ["gleam"], requirements = ["gleam_stdlib", "ranger"], otp_app = "birl", source = "hex", outer_checksum = "5C66647D62BCB11FE327E7A6024907C4A17954EF22865FE0940B54A852446D01" },
|
||||||
|
{ name = "decode", version = "0.5.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "decode", source = "hex", outer_checksum = "05E14DC95A550BA51B8774485B04894B87A898C588B9B1C920104B110AED218B" },
|
||||||
|
{ name = "filepath", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "67A6D15FB39EEB69DD31F8C145BB5A421790581BD6AA14B33D64D5A55DBD6587" },
|
||||||
{ name = "gleam_erlang", version = "0.32.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "B18643083A0117AC5CFD0C1AEEBE5469071895ECFA426DCC26517A07F6AD9948" },
|
{ name = "gleam_erlang", version = "0.32.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "B18643083A0117AC5CFD0C1AEEBE5469071895ECFA426DCC26517A07F6AD9948" },
|
||||||
|
{ name = "gleam_json", version = "2.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_json", source = "hex", outer_checksum = "0A57FB5666E695FD2BEE74C0428A98B0FC11A395D2C7B4CDF5E22C5DD32C74C6" },
|
||||||
{ name = "gleam_otp", version = "0.14.1", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "5A8CE8DBD01C29403390A7BD5C0A63D26F865C83173CF9708E6E827E53159C65" },
|
{ name = "gleam_otp", version = "0.14.1", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "5A8CE8DBD01C29403390A7BD5C0A63D26F865C83173CF9708E6E827E53159C65" },
|
||||||
{ name = "gleam_stdlib", version = "0.45.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "206FCE1A76974AECFC55AEBCD0217D59EDE4E408C016E2CFCCC8FF51278F186E" },
|
{ 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 = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" },
|
||||||
{ name = "ranger", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "ranger", source = "hex", outer_checksum = "B8F3AFF23A3A5B5D9526B8D18E7C43A7DFD3902B151B97EC65397FE29192B695" },
|
{ name = "ranger", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "ranger", source = "hex", outer_checksum = "B8F3AFF23A3A5B5D9526B8D18E7C43A7DFD3902B151B97EC65397FE29192B695" },
|
||||||
|
{ name = "simplifile", version = "2.2.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0DFABEF7DC7A9E2FF4BB27B108034E60C81BEBFCB7AB816B9E7E18ED4503ACD8" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[requirements]
|
[requirements]
|
||||||
birl = { version = ">= 1.7.1 and < 2.0.0" }
|
birl = { version = ">= 1.7.1 and < 2.0.0" }
|
||||||
|
decode = { version = ">= 0.5.0 and < 1.0.0" }
|
||||||
|
gleam_json = { version = ">= 2.1.0 and < 3.0.0" }
|
||||||
gleam_otp = { version = ">= 0.14.1 and < 1.0.0" }
|
gleam_otp = { version = ">= 0.14.1 and < 1.0.0" }
|
||||||
gleam_stdlib = { version = ">= 0.45.0 and < 2.0.0" }
|
gleam_stdlib = { version = ">= 0.45.0 and < 2.0.0" }
|
||||||
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
|
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
|
||||||
|
simplifile = { version = ">= 2.2.0 and < 3.0.0" }
|
||||||
|
|||||||
119
src/json_serde.gleam
Normal file
119
src/json_serde.gleam
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
//// Functions to allow serialization from Tree to Json and back!
|
||||||
|
|
||||||
|
import decode/zero
|
||||||
|
import gleam/dict
|
||||||
|
import gleam/dynamic
|
||||||
|
|
||||||
|
import gleam/json.{bool, float, int, null, object, string}
|
||||||
|
import gleam/list
|
||||||
|
|
||||||
|
import gleam/result
|
||||||
|
|
||||||
|
import tree
|
||||||
|
|
||||||
|
pub type JsonCodecError {
|
||||||
|
EncodingError
|
||||||
|
DecodingError
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serialize(tree) {
|
||||||
|
tree |> tree_to_json |> json.to_string
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tree_to_json(tree: tree.Tree) -> json.Json {
|
||||||
|
case tree {
|
||||||
|
tree.Leaf(_) as lf -> leaf_to_json(lf)
|
||||||
|
tree.Node(children) | tree.Root(children) -> {
|
||||||
|
children
|
||||||
|
|> dict.to_list
|
||||||
|
|> list.map(fn(pair) {
|
||||||
|
let #(k, v) = pair
|
||||||
|
#(k, v |> tree_to_json)
|
||||||
|
})
|
||||||
|
|> object()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn leaf_to_json(tree: tree.Tree) -> json.Json {
|
||||||
|
case tree {
|
||||||
|
tree.Leaf(data) ->
|
||||||
|
case data {
|
||||||
|
tree.Bool(b) -> bool(b)
|
||||||
|
tree.Float(f) -> float(f)
|
||||||
|
tree.Int(i) -> int(i)
|
||||||
|
tree.Null -> null()
|
||||||
|
tree.String(s) -> string(s)
|
||||||
|
}
|
||||||
|
_ -> panic as "Tried to serialize not a Leaf."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize(string) {
|
||||||
|
case json.decode(string, zero.run(_, zero.dynamic)) {
|
||||||
|
Error(_) -> Error(DecodingError)
|
||||||
|
Ok(data) -> data |> tree_decoder(True) |> Ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tree_decoder(data, root) {
|
||||||
|
let _ = case dynamic.classify(data), root {
|
||||||
|
"Dict", True -> {
|
||||||
|
let children =
|
||||||
|
zero.dict(zero.string, zero.dynamic)
|
||||||
|
|> zero.run(data, _)
|
||||||
|
|
||||||
|
case children {
|
||||||
|
Error(_) -> panic as "EncodingError"
|
||||||
|
Ok(children) ->
|
||||||
|
children
|
||||||
|
|> dict.map_values(fn(_, v) { tree_decoder(v, False) })
|
||||||
|
|> tree.Root
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"Dict", False -> {
|
||||||
|
let children =
|
||||||
|
zero.dict(zero.string, zero.dynamic)
|
||||||
|
|> zero.run(data, _)
|
||||||
|
|
||||||
|
case children {
|
||||||
|
Error(_) -> panic as "EncodingError"
|
||||||
|
Ok(children) ->
|
||||||
|
children
|
||||||
|
|> dict.map_values(fn(_, v) { tree_decoder(v, False) })
|
||||||
|
}
|
||||||
|
|> tree.Node
|
||||||
|
}
|
||||||
|
_, _ ->
|
||||||
|
case leaf_decoder(data) {
|
||||||
|
Error(_) -> panic as "EncodingError"
|
||||||
|
Ok(leaf) -> leaf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn leaf_decoder(data) {
|
||||||
|
let decoded = case dynamic.classify(data) {
|
||||||
|
"Int" -> {
|
||||||
|
use value <- result.try(dynamic.int(data))
|
||||||
|
Ok(tree.Int(value))
|
||||||
|
}
|
||||||
|
"Float" -> {
|
||||||
|
use value <- result.try(dynamic.float(data))
|
||||||
|
Ok(tree.Float(value))
|
||||||
|
}
|
||||||
|
"Bool" -> {
|
||||||
|
use value <- result.try(dynamic.bool(data))
|
||||||
|
Ok(tree.Bool(value))
|
||||||
|
}
|
||||||
|
"String" -> {
|
||||||
|
use value <- result.try(dynamic.string(data))
|
||||||
|
Ok(tree.String(value))
|
||||||
|
}
|
||||||
|
_ -> Ok(tree.Null)
|
||||||
|
}
|
||||||
|
|
||||||
|
use data <- result.try(decoded)
|
||||||
|
Ok(tree.Leaf(data))
|
||||||
|
}
|
||||||
@ -1,6 +1,3 @@
|
|||||||
import gleam/io
|
|
||||||
import gleam/string
|
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
".a.b.c" |> string.split(".") |> io.debug
|
todo
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import gleam/dict
|
import gleam/dict
|
||||||
import gleeunit
|
import gleeunit
|
||||||
import gleeunit/should
|
import gleeunit/should
|
||||||
|
import json_serde
|
||||||
import query
|
import query
|
||||||
import tree
|
import tree
|
||||||
|
|
||||||
@ -51,3 +52,17 @@ pub fn tree_test() {
|
|||||||
query.get(tree, ".a2.b3", False)
|
query.get(tree, ".a2.b3", False)
|
||||||
|> should.equal(tree.Leaf(tree.Int(43)) |> Ok())
|
|> should.equal(tree.Leaf(tree.Int(43)) |> Ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn json_test() {
|
||||||
|
let tree = tree.new()
|
||||||
|
let assert Ok(tree) = query.set(tree, ".a.b.c.d", tree.String("foo"))
|
||||||
|
let assert Ok(tree) = query.set(tree, ".a.b2.c", tree.String("bar"))
|
||||||
|
let assert Ok(tree) = query.set(tree, ".a.b", tree.String("new foo"))
|
||||||
|
let assert Ok(tree) = query.set(tree, ".a2.b3", tree.Int(42))
|
||||||
|
let assert Ok(tree) = query.set(tree, ".a2.b3", tree.Int(43))
|
||||||
|
|
||||||
|
let json = tree |> json_serde.serialize
|
||||||
|
let assert Ok(decoded) = json |> json_serde.deserialize()
|
||||||
|
|
||||||
|
should.equal(tree, decoded)
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user