From 34e1d0136fcadfc3bf1502c952bc5bfb755926a9 Mon Sep 17 00:00:00 2001 From: Gavin Morrow Date: Wed, 29 Jul 2026 11:58:18 -0400 Subject: [PATCH] Add JSON encoders --- gleam.toml | 1 + manifest.toml | 1 + src/dnd_inventory_tracker/inventory.gleam | 45 +++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/gleam.toml b/gleam.toml index 265fa54..8dbe475 100644 --- a/gleam.toml +++ b/gleam.toml @@ -16,6 +16,7 @@ target = "javascript" [dependencies] gleam_stdlib = ">= 1.0.0 and < 2.0.0" lustre = ">= 5.7.1 and < 6.0.0" +gleam_json = ">= 3.1.0 and < 4.0.0" [dev_dependencies] gleeunit = ">= 1.0.0 and < 2.0.0" diff --git a/manifest.toml b/manifest.toml index 0c9027b..cc593b0 100644 --- a/manifest.toml +++ b/manifest.toml @@ -46,6 +46,7 @@ packages = [ ] [requirements] +gleam_json = { version = ">= 3.1.0 and < 4.0.0" } gleam_stdlib = { version = ">= 1.0.0 and < 2.0.0" } gleeunit = { version = ">= 1.0.0 and < 2.0.0" } lustre = { version = ">= 5.7.1 and < 6.0.0" } diff --git a/src/dnd_inventory_tracker/inventory.gleam b/src/dnd_inventory_tracker/inventory.gleam index 083dc38..fff83a5 100644 --- a/src/dnd_inventory_tracker/inventory.gleam +++ b/src/dnd_inventory_tracker/inventory.gleam @@ -1,5 +1,6 @@ import gleam/bool import gleam/dynamic/decode +import gleam/json pub type Inventory { Inventory( @@ -17,6 +18,22 @@ const inventory_default = Inventory( coins_count_towards_weight_limit: False, ) +pub fn inventory_to_json(inventory: Inventory) -> json.Json { + let Inventory(name:, items:, weight_limit:, coins_count_towards_weight_limit:) = + inventory + + json.object([ + #("version", json.string("1.0")), + #("name", json.string(name)), + #("items", json.array(items, item_to_json)), + #("weight_limit", weight_to_json(weight_limit)), + #( + "coins_count_towards_weight_limit", + json.bool(coins_count_towards_weight_limit), + ), + ]) +} + pub fn inventory_decoder() -> decode.Decoder(Inventory) { use version <- decode.field("version", decode.string) use <- bool.guard( @@ -48,6 +65,19 @@ pub type Item { ) } +fn item_to_json(item: Item) -> json.Json { + let Item(name:, category:, kind:, cost:, weight:, description:, stats:) = item + json.object([ + #("name", json.string(name)), + #("category", json.string(category)), + #("kind", item_kind_to_json(kind)), + #("cost", json.string(cost)), + #("weight", weight_to_json(weight)), + #("description", json.string(description)), + #("stats", json.array(stats, json.string)), + ]) +} + fn item_decoder() -> decode.Decoder(Item) { use name <- decode.field("name", decode.string) use category <- decode.field("category", decode.string) @@ -67,6 +97,14 @@ pub type ItemKind { Other } +fn item_kind_to_json(item_kind: ItemKind) -> json.Json { + case item_kind { + Armor -> json.string("armor") + Coin -> json.string("coin") + Other -> json.string("other") + } +} + fn item_kind_decoder() -> decode.Decoder(ItemKind) { use variant <- decode.then(decode.string) case variant { @@ -81,6 +119,13 @@ pub type Weight { Pounds(lbs: Int) } +fn weight_to_json(weight: Weight) -> json.Json { + let Pounds(lbs:) = weight + json.object([ + #("lbs", json.int(lbs)), + ]) +} + fn weight_decoder() -> decode.Decoder(Weight) { use lbs <- decode.field("lbs", decode.int) Pounds(lbs:) |> decode.success -- 2.51.2