From 41c3cda464989f5059f68da0efdbffc93b0fad26 Mon Sep 17 00:00:00 2001 From: Fea Date: Tue, 12 Mar 2024 12:10:15 +0100 Subject: [PATCH] Adapt to parse structure suggested in https://github.com/NixOS/nixpkgs/issues/198655#issuecomment-1985943125 --- README.md | 12 +++++++----- examples/example.json | 14 ++++++++------ src/main.rs | 39 +++++++++++++++++++++++++-------------- 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 1f2dc05..c872f2e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,9 @@ json2kdl is a program that generates KDL files from JSON -![A terminal screenshot of me running cat to show the contents of an example json file, then running json2kdl on it and showing the kdl output in a new file](https://eldritchcafe.files.fedi.monster/media_attachments/files/109/972/564/372/013/139/original/ab2e73d17967d369.png) +```sh +json2kdl input.json output.kdl +``` ## Intended Use @@ -10,13 +12,13 @@ json2kdl was made specifically for [Nixpkgs Issue #198655](https://github.com/Ni which means, these features are currently out of scope: - Parsing arbitrary JSON Currently, the input file structure must follow a specific schema: - - [Nodes](https://github.com/kdl-org/kdl/blob/main/SPEC.md#node) can be defined as fields of the root JSON object (`{}`) - - Each node can have these optional fields: + - [Nodes](https://github.com/kdl-org/kdl/blob/main/SPEC.md#node) can be defined as elements of the root JSON array (`[]`) + - Each node must have the `identifier` field of type [Identifier](https://github.com/kdl-org/kdl/blob/main/SPEC.md#identifier) and can have these optional fields: - `arguments` (Array of [Values](https://github.com/kdl-org/kdl/blob/main/SPEC.md#value)) - `properties` (Object with [Identifier](https://github.com/kdl-org/kdl/blob/main/SPEC.md#identifier):[Value](https://github.com/kdl-org/kdl/blob/main/SPEC.md#value) pairs) - - `children` (Object with fields representing [Nodes](https://github.com/kdl-org/kdl/blob/main/SPEC.md#node)) + - `children` (Array of objects representing [Nodes](https://github.com/kdl-org/kdl/blob/main/SPEC.md#node)) See `examples/example.json` - Comments (As JSON does not support them) - Type Annotations -- Types that KDL has but JSON does not and vice versa \ No newline at end of file +- Types that KDL has but JSON does not and vice versa diff --git a/examples/example.json b/examples/example.json index 0ab35fd..601ce88 100644 --- a/examples/example.json +++ b/examples/example.json @@ -1,17 +1,19 @@ -{ - "thermal-paste": { +[ + { + "identifier": "thermal-paste", "arguments": [ "NT-H1" ], - "children": { - "description": { + "children": [ + { + "identifier": "description", "arguments": [ "it tastes nice:)" ] } - }, + ], "properties": { "amount": "3.5g" } } -} \ No newline at end of file +] diff --git a/src/main.rs b/src/main.rs index fe5e072..59c3223 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,11 +29,16 @@ fn main() -> Result<()> { fn json_to_kdl(json: Value) -> Result { let nodes: Vec> = json - .as_object() - .ok_or_else(|| miette!("Document root must be a JSON object"))? + .as_array() + .ok_or_else(|| miette!("Document root must be a JSON array"))? .iter() - .map(|(key, value)| { - let mut node = KdlNode::new(key.as_str()); + .map(|value| { + let mut node = KdlNode::new( + value + .get("identifier") + .and_then(|ident| ident.as_str()) + .ok_or_else(|| miette!("`identifier` must exist and be a String"))?, + ); if let Some(arguments) = value.get("arguments") { let args: Vec = arguments @@ -105,8 +110,9 @@ fn value_to_kdl(value: Value) -> Result { #[test] fn test_conversion() -> Result<()> { let input = serde_json::json!( - { - "bees": { + [ + { + "identifier": "bees", "arguments": [ true, 42, @@ -119,22 +125,27 @@ fn test_conversion() -> Result<()> { "state?": "quite upset" } }, - "lemon": { - "children": { - "child": { + { + "identifier": "lemon", + "children": [ + { + "identifier": "child", "properties": { "age": 3 - } + } }, - "child-eater": { + { + "identifier": "child-eater", "arguments": [ ":^)" ] } - } + ] }, - "ohno": {} - }); + { + "identifier": "ohno" + } + ]); assert_eq!( json_to_kdl(input)?.to_string(),