This commit is contained in:
Fea 2024-03-12 12:10:15 +01:00 committed by Agatha Lovelace
parent dd939ae1f6
commit 41c3cda464
3 changed files with 40 additions and 25 deletions

View File

@ -2,7 +2,9 @@
json2kdl is a program that generates KDL files from JSON 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 ## 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: which means, these features are currently out of scope:
- Parsing arbitrary JSON - Parsing arbitrary JSON
Currently, the input file structure must follow a specific schema: 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 (`{}`) - [Nodes](https://github.com/kdl-org/kdl/blob/main/SPEC.md#node) can be defined as elements of the root JSON array (`[]`)
- Each node can have these optional fields: - 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)) - `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) - `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` See `examples/example.json`
- Comments (As JSON does not support them) - Comments (As JSON does not support them)
- Type Annotations - Type Annotations
- Types that KDL has but JSON does not and vice versa - Types that KDL has but JSON does not and vice versa

View File

@ -1,17 +1,19 @@
{ [
"thermal-paste": { {
"identifier": "thermal-paste",
"arguments": [ "arguments": [
"NT-H1" "NT-H1"
], ],
"children": { "children": [
"description": { {
"identifier": "description",
"arguments": [ "arguments": [
"it tastes nice:)" "it tastes nice:)"
] ]
} }
}, ],
"properties": { "properties": {
"amount": "3.5g" "amount": "3.5g"
} }
} }
} ]

View File

@ -29,11 +29,16 @@ fn main() -> Result<()> {
fn json_to_kdl(json: Value) -> Result<KdlDocument> { fn json_to_kdl(json: Value) -> Result<KdlDocument> {
let nodes: Vec<Result<KdlNode>> = json let nodes: Vec<Result<KdlNode>> = json
.as_object() .as_array()
.ok_or_else(|| miette!("Document root must be a JSON object"))? .ok_or_else(|| miette!("Document root must be a JSON array"))?
.iter() .iter()
.map(|(key, value)| { .map(|value| {
let mut node = KdlNode::new(key.as_str()); 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") { if let Some(arguments) = value.get("arguments") {
let args: Vec<KdlValue> = arguments let args: Vec<KdlValue> = arguments
@ -105,8 +110,9 @@ fn value_to_kdl(value: Value) -> Result<KdlValue> {
#[test] #[test]
fn test_conversion() -> Result<()> { fn test_conversion() -> Result<()> {
let input = serde_json::json!( let input = serde_json::json!(
{ [
"bees": { {
"identifier": "bees",
"arguments": [ "arguments": [
true, true,
42, 42,
@ -119,22 +125,27 @@ fn test_conversion() -> Result<()> {
"state?": "quite upset" "state?": "quite upset"
} }
}, },
"lemon": { {
"children": { "identifier": "lemon",
"child": { "children": [
{
"identifier": "child",
"properties": { "properties": {
"age": 3 "age": 3
} }
}, },
"child-eater": { {
"identifier": "child-eater",
"arguments": [ "arguments": [
":^)" ":^)"
] ]
} }
} ]
}, },
"ohno": {} {
}); "identifier": "ohno"
}
]);
assert_eq!( assert_eq!(
json_to_kdl(input)?.to_string(), json_to_kdl(input)?.to_string(),