Adapt to parse structure suggested in https://github.com/NixOS/nixpkgs/issues/198655#issuecomment-1985943125
This commit is contained in:
parent
dd939ae1f6
commit
41c3cda464
12
README.md
12
README.md
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
|
|
39
src/main.rs
39
src/main.rs
|
@ -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(),
|
||||||
|
|
Loading…
Reference in New Issue