2022-06-01 17:55:55 +03:00
|
|
|
# to jq-flavoured json
|
2022-12-21 15:59:54 +03:00
|
|
|
def _to_jq($opts):
|
2022-06-01 17:55:55 +03:00
|
|
|
def _is_ident: test("^[a-zA-Z_][a-zA-Z_0-9]*$");
|
|
|
|
def _key: if _is_ident | not then tojson end;
|
|
|
|
def _f($opts; $indent):
|
|
|
|
def _r($prefix):
|
|
|
|
( type as $t
|
|
|
|
| if $t == "null" then tojson
|
|
|
|
elif $t == "string" then tojson
|
|
|
|
elif $t == "number" then tojson
|
|
|
|
elif $t == "boolean" then tojson
|
|
|
|
elif $t == "array" then
|
|
|
|
if length == 0 then "[]"
|
|
|
|
else
|
|
|
|
[ "[", $opts.compound_newline
|
|
|
|
, ( [ .[]
|
|
|
|
| $prefix, $indent
|
|
|
|
, _r($prefix+$indent), $opts.array_sep
|
|
|
|
]
|
|
|
|
| .[0:-1]
|
|
|
|
)
|
|
|
|
, $opts.compound_newline
|
|
|
|
, $prefix, "]"
|
|
|
|
]
|
|
|
|
end
|
|
|
|
elif $t == "object" then
|
|
|
|
if length == 0 then "{}"
|
|
|
|
else
|
|
|
|
[ "{", $opts.compound_newline
|
|
|
|
, ( [ to_entries[]
|
|
|
|
| $prefix, $indent
|
|
|
|
, (.key | _key), $opts.key_sep
|
|
|
|
, (.value | _r($prefix+$indent)), $opts.object_sep
|
|
|
|
]
|
|
|
|
| .[0:-1]
|
|
|
|
)
|
|
|
|
, $opts.compound_newline
|
|
|
|
, $prefix, "}"
|
|
|
|
]
|
|
|
|
end
|
|
|
|
else error("unknown type \($t)")
|
|
|
|
end
|
|
|
|
);
|
|
|
|
_r("");
|
|
|
|
( _f($opts; $opts.indent * " ")
|
|
|
|
| if _is_array then flatten | join("") end
|
|
|
|
);
|
2022-12-21 15:59:54 +03:00
|
|
|
def to_jq($opts):
|
|
|
|
_to_jq(
|
2023-07-27 14:21:04 +03:00
|
|
|
( { indent: 0
|
|
|
|
, key_sep: ":"
|
|
|
|
, object_sep: ","
|
|
|
|
, array_sep: ","
|
|
|
|
, compound_newline: "",
|
2022-06-01 17:55:55 +03:00
|
|
|
} + $opts
|
|
|
|
| if .indent > 0 then
|
|
|
|
( .key_sep = ": "
|
|
|
|
| .object_sep = ",\n"
|
|
|
|
| .array_sep = ",\n"
|
|
|
|
| .compound_newline = "\n"
|
|
|
|
)
|
|
|
|
end
|
|
|
|
)
|
|
|
|
);
|
2022-12-21 15:59:54 +03:00
|
|
|
def to_jq: to_jq(null);
|
2022-06-01 17:55:55 +03:00
|
|
|
|
|
|
|
# from jq-flavoured json
|
2022-12-21 15:59:54 +03:00
|
|
|
def from_jq:
|
2022-06-01 17:55:55 +03:00
|
|
|
def _f:
|
|
|
|
( . as $v
|
|
|
|
| .term.type
|
|
|
|
| if . == "TermTypeNull" then null
|
|
|
|
elif . == "TermTypeTrue" then true
|
|
|
|
elif . == "TermTypeFalse" then false
|
2023-10-20 15:03:52 +03:00
|
|
|
elif . == "TermTypeString" then
|
|
|
|
if $v.term.str.queries then error("string interpolation")
|
|
|
|
else $v.term.str.str
|
|
|
|
end
|
2022-06-01 17:55:55 +03:00
|
|
|
elif . == "TermTypeNumber" then $v.term.number | tonumber
|
|
|
|
elif . == "TermTypeObject" then
|
|
|
|
( $v.term.object.key_vals // []
|
|
|
|
| map(
|
2023-07-27 14:21:04 +03:00
|
|
|
{ key: (.key // .key_string.str)
|
|
|
|
, value: (.val.queries[0] | _f)
|
2022-06-01 17:55:55 +03:00
|
|
|
}
|
|
|
|
)
|
|
|
|
| from_entries
|
|
|
|
)
|
|
|
|
elif . == "TermTypeArray" then
|
|
|
|
( def _a: if .op then .left, .right | _a end;
|
|
|
|
[$v.term.array.query // empty | _a | _f]
|
|
|
|
)
|
2023-10-20 15:03:52 +03:00
|
|
|
else error("unsupported term \($v.term.type)")
|
2022-06-01 17:55:55 +03:00
|
|
|
end
|
|
|
|
);
|
|
|
|
try
|
|
|
|
(_query_fromstring | _f)
|
|
|
|
catch
|
2023-10-20 15:03:52 +03:00
|
|
|
error("from_jq only supports constant literals: \(.)");
|