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
![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
- Types that KDL has but JSON does not and vice versa

View File

@ -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"
}
}
}
]

View File

@ -29,11 +29,16 @@ fn main() -> Result<()> {
fn json_to_kdl(json: Value) -> Result<KdlDocument> {
let nodes: Vec<Result<KdlNode>> = 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<KdlValue> = arguments
@ -105,8 +110,9 @@ fn value_to_kdl(value: Value) -> Result<KdlValue> {
#[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(),