Compare commits

..

3 Commits

Author SHA1 Message Date
LilyRose2798 af699e4b23 Bump version 2024-03-25 14:19:19 +11:00
LilyRose2798 fe6a3deb98 Add json stringify 2024-03-25 14:16:08 +11:00
LilyRose2798 7a10039d79 Add jsonl parsing 2024-03-25 13:15:27 +11:00
2 changed files with 126 additions and 3 deletions

View File

@ -1,5 +1,5 @@
name = "jasper" name = "jasper"
version = "1.1.2" version = "1.2.0"
description = "Utilities for parsing and querying JSON data" description = "Utilities for parsing and querying JSON data"
licences = ["AGPL-3.0-only"] licences = ["AGPL-3.0-only"]

View File

@ -18,8 +18,8 @@ pub type ParseError {
} }
fn run_parser( fn run_parser(
parser: pears.Parser(Char, a),
input: String, input: String,
parser: pears.Parser(Char, a),
) -> Result(a, ParseError) { ) -> Result(a, ParseError) {
case parser(chars.input(input)) { case parser(chars.input(input)) {
Ok(pears.Parsed(_, j)) -> Ok(j) Ok(pears.Parsed(_, j)) -> Ok(j)
@ -168,7 +168,130 @@ fn json_parser() -> Parser(Char, JsonValue) {
} }
pub fn parse_json(value: String) -> Result(JsonValue, ParseError) { pub fn parse_json(value: String) -> Result(JsonValue, ParseError) {
run_parser(json_parser(), value) run_parser(value, json_parser())
}
fn stringify_json_spaced_rec(
value: JsonValue,
space: String,
depth: Int,
) -> String {
case value {
Object(obj) ->
case dict.to_list(obj) {
[] -> "{}"
ls ->
"{\n"
<> string.repeat(space, depth + 1)
<> {
list.map(ls, fn(kv) {
"\""
<> kv.0
<> "\": "
<> stringify_json_spaced_rec(kv.1, space, depth + 1)
})
|> string.join(",\n" <> string.repeat(space, depth + 1))
}
<> "\n"
<> string.repeat(space, depth)
<> "}"
}
Array([]) -> "[]"
Array(arr) ->
"[\n"
<> string.repeat(space, depth + 1)
<> {
arr
|> list.map(stringify_json_spaced_rec(_, space, depth + 1))
|> string.join(",\n" <> string.repeat(space, depth + 1))
}
<> "\n"
<> string.repeat(space, depth)
<> "]"
String(str) -> "\"" <> str <> "\""
Number(flt) -> float.to_string(flt)
Boolean(True) -> "true"
Boolean(False) -> "false"
Null -> "null"
}
}
pub type Indentation {
Spaces(Int)
Tab
Tabs(Int)
}
pub fn stringify_json_spaced(
value: JsonValue,
indentation: Indentation,
) -> String {
stringify_json_spaced_rec(
value,
case indentation {
Spaces(n) -> string.repeat(" ", n)
Tab -> "\t"
Tabs(n) -> string.repeat("\t", n)
},
0,
)
}
pub fn stringify_json(value: JsonValue) -> String {
case value {
Object(obj) ->
"{"
<> {
obj
|> dict.to_list
|> list.map(fn(kv) { "\"" <> kv.0 <> "\":" <> stringify_json(kv.1) })
|> string.join(",")
}
<> "}"
Array(arr) ->
"["
<> {
arr
|> list.map(stringify_json)
|> string.join(",")
}
<> "]"
String(str) -> "\"" <> str <> "\""
Number(flt) -> float.to_string(flt)
Boolean(True) -> "true"
Boolean(False) -> "false"
Null -> "null"
}
}
pub fn stringify_jsonl(values: List(JsonValue)) -> String {
values
|> list.map(stringify_json)
|> string.join("\n")
}
fn split_jsonl(value: String) -> List(String) {
case string.last(value) {
Ok("\n") -> string.drop_right(value, 1)
_ -> value
}
|> string.split("\n")
}
pub fn parse_jsonl(value: String) -> Result(List(JsonValue), ParseError) {
let parse = run_parser(_, json_parser())
list.try_map(split_jsonl(value), parse)
}
pub fn parse_jsonl_all(value: String) -> List(Result(JsonValue, ParseError)) {
let parse = run_parser(_, json_parser())
list.map(split_jsonl(value), parse)
}
pub fn parse_jsonl_valid(value: String) -> List(JsonValue) {
value
|> parse_jsonl_all
|> result.values
} }
pub type JsonQuery { pub type JsonQuery {