Packages

KDL v2 parser, serializer, normalizer, and document builder for Gleam

Current section

Files

Jump to
kdleam src kdleam@json.erl
Raw

src/kdleam@json.erl

-module(kdleam@json).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/kdleam/json.gleam").
-export([document_to_json/1, error_to_json/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(" KDL 文書と解析エラーを素朴な JSON 文字列へ変換する。\n").
-file("src/kdleam/json.gleam", 240).
-spec hex4(integer()) -> binary().
hex4(I) ->
Hex = case gleam@int:to_base_string(I, 16) of
{ok, V} ->
string:lowercase(V);
{error, _} ->
<<"0"/utf8>>
end,
gleam@string:pad_start(Hex, 4, <<"0"/utf8>>).
-file("src/kdleam/json.gleam", 220).
-spec escape_codepoint(integer()) -> binary().
escape_codepoint(Cp) ->
I = gleam_stdlib:identity(Cp),
case I of
16#22 ->
<<"\\\""/utf8>>;
16#5C ->
<<"\\\\"/utf8>>;
16#08 ->
<<"\\b"/utf8>>;
16#0C ->
<<"\\f"/utf8>>;
16#0A ->
<<"\\n"/utf8>>;
16#0D ->
<<"\\r"/utf8>>;
16#09 ->
<<"\\t"/utf8>>;
16#2028 ->
<<"\\u2028"/utf8>>;
16#2029 ->
<<"\\u2029"/utf8>>;
_ ->
case I < 16#20 of
true ->
<<"\\u"/utf8, (hex4(I))/binary>>;
false ->
gleam_stdlib:utf_codepoint_list_to_string([Cp])
end
end.
-file("src/kdleam/json.gleam", 213).
-spec escape_chars(list(integer()), binary()) -> binary().
escape_chars(Codepoints, Acc) ->
case Codepoints of
[] ->
Acc;
[Cp | Rest] ->
escape_chars(Rest, <<Acc/binary, (escape_codepoint(Cp))/binary>>)
end.
-file("src/kdleam/json.gleam", 209).
-spec encode_string(binary()) -> binary().
encode_string(S) ->
<<<<"\""/utf8,
(escape_chars(gleam@string:to_utf_codepoints(S), <<""/utf8>>))/binary>>/binary,
"\""/utf8>>.
-file("src/kdleam/json.gleam", 121).
-spec encode_optional_string(gleam@option:option(binary())) -> binary().
encode_optional_string(Value) ->
case Value of
none ->
<<"null"/utf8>>;
{some, S} ->
encode_string(S)
end.
-file("src/kdleam/json.gleam", 173).
-spec is_float_decimal(binary()) -> boolean().
is_float_decimal(Body) ->
(gleam_stdlib:contains_string(Body, <<"."/utf8>>) orelse gleam_stdlib:contains_string(
Body,
<<"e"/utf8>>
))
orelse gleam_stdlib:contains_string(Body, <<"E"/utf8>>).
-file("src/kdleam/json.gleam", 194).
-spec try_radix(binary(), list({binary(), integer()})) -> {integer(), binary()}.
try_radix(Rest, Prefixes) ->
case Prefixes of
[] ->
{10, Rest};
[{Prefix, Base} | Others] ->
Body = gleam_stdlib:string_remove_prefix(Rest, Prefix),
case Body /= Rest of
true ->
{Base, Body};
false ->
try_radix(Rest, Others)
end
end.
-file("src/kdleam/json.gleam", 190).
-spec radix_body(binary()) -> {integer(), binary()}.
radix_body(Rest) ->
try_radix(Rest, kdleam@scanner:radix_prefixes()).
-file("src/kdleam/json.gleam", 179).
-spec remove_sign(binary()) -> {binary(), binary()}.
remove_sign(Raw) ->
Minus = gleam_stdlib:string_remove_prefix(Raw, <<"-"/utf8>>),
case Minus /= Raw of
true ->
{<<"-"/utf8>>, Minus};
false ->
Plus = gleam_stdlib:string_remove_prefix(Raw, <<"+"/utf8>>),
{<<""/utf8>>, Plus}
end.
-file("src/kdleam/json.gleam", 154).
-spec decimal_of_raw(binary()) -> gleam@option:option(binary()).
decimal_of_raw(Raw) ->
case gleam_stdlib:string_starts_with(Raw, <<"#"/utf8>>) of
true ->
none;
false ->
{Sign, Rest} = remove_sign(Raw),
{Base, Body} = radix_body(Rest),
case (Base =:= 10) andalso is_float_decimal(Body) of
true ->
none;
false ->
case kdleam@bignum:base_to_decimal(
kdleam@scanner:clean_underscores(Body),
Base
) of
{ok, <<"0"/utf8>>} ->
{some, <<"0"/utf8>>};
{ok, Decimal} ->
{some, <<Sign/binary, Decimal/binary>>};
{error, _} ->
none
end
end
end.
-file("src/kdleam/json.gleam", 114).
-spec encode_decimal(binary()) -> binary().
encode_decimal(Raw) ->
case decimal_of_raw(Raw) of
{some, Decimal} ->
encode_string(Decimal);
none ->
<<"null"/utf8>>
end.
-file("src/kdleam/json.gleam", 106).
-spec encode_number(binary()) -> binary().
encode_number(Raw) ->
<<<<<<<<"{\"kind\":\"number\",\"raw\":"/utf8, (encode_string(Raw))/binary>>/binary,
",\"decimal\":"/utf8>>/binary,
(encode_decimal(Raw))/binary>>/binary,
"}"/utf8>>.
-file("src/kdleam/json.gleam", 91).
-spec encode_value(kdleam@document:kdl_value()) -> binary().
encode_value(Value) ->
case Value of
{kdl_string, S} ->
<<<<"{\"kind\":\"string\",\"value\":"/utf8,
(encode_string(S))/binary>>/binary,
"}"/utf8>>;
{kdl_number_value, Number} ->
encode_number(kdleam@document:number_raw(Number));
{kdl_bool, B} ->
<<<<"{\"kind\":\"bool\",\"value\":"/utf8, (case B of
true ->
<<"true"/utf8>>;
false ->
<<"false"/utf8>>
end)/binary>>/binary, "}"/utf8>>;
kdl_null ->
<<"{\"kind\":\"null\"}"/utf8>>
end.
-file("src/kdleam/json.gleam", 72).
-spec encode_entry(kdleam@document:kdl_entry()) -> binary().
encode_entry(Entry) ->
case Entry of
{kdl_argument, Ty, Value} ->
<<<<<<<<"{\"kind\":\"argument\",\"ty\":"/utf8,
(encode_optional_string(Ty))/binary>>/binary,
",\"value\":"/utf8>>/binary,
(encode_value(Value))/binary>>/binary,
"}"/utf8>>;
{kdl_property, Key, Ty@1, Value@1} ->
<<<<<<<<<<<<"{\"kind\":\"property\",\"key\":"/utf8,
(encode_string(Key))/binary>>/binary,
",\"ty\":"/utf8>>/binary,
(encode_optional_string(Ty@1))/binary>>/binary,
",\"value\":"/utf8>>/binary,
(encode_value(Value@1))/binary>>/binary,
"}"/utf8>>
end.
-file("src/kdleam/json.gleam", 64).
-spec encode_children(gleam@option:option(list(kdleam@document:kdl_node()))) -> binary().
encode_children(Children) ->
case Children of
none ->
<<"null"/utf8>>;
{some, Nodes} ->
<<<<"["/utf8,
(begin
_pipe = Nodes,
_pipe@1 = gleam@list:map(_pipe, fun encode_node/1),
gleam@string:join(_pipe@1, <<","/utf8>>)
end)/binary>>/binary,
"]"/utf8>>
end.
-file("src/kdleam/json.gleam", 45).
-spec encode_node(kdleam@document:kdl_node()) -> binary().
encode_node(Node) ->
Name = kdleam@document:name(Node),
Ty = kdleam@document:ty(Node),
Entries = begin
_pipe = kdleam@document:entries(Node),
_pipe@1 = gleam@list:map(_pipe, fun encode_entry/1),
gleam@string:join(_pipe@1, <<","/utf8>>)
end,
Children = kdleam@document:children(Node),
<<<<<<<<<<<<<<<<"{\"name\":"/utf8, (encode_string(Name))/binary>>/binary,
",\"ty\":"/utf8>>/binary,
(encode_optional_string(Ty))/binary>>/binary,
",\"entries\":["/utf8>>/binary,
Entries/binary>>/binary,
"],\"children\":"/utf8>>/binary,
(encode_children(Children))/binary>>/binary,
"}"/utf8>>.
-file("src/kdleam/json.gleam", 21).
?DOC(" 文書をバックエンドに依存しない素朴な JSON 文字列へ全域で変換する。\n").
-spec document_to_json(kdleam@document:kdl_document()) -> binary().
document_to_json(Doc) ->
Nodes = begin
_pipe = kdleam@document:nodes(Doc),
_pipe@1 = gleam@list:map(_pipe, fun encode_node/1),
gleam@string:join(_pipe@1, <<","/utf8>>)
end,
<<<<"{\"nodes\":["/utf8, Nodes/binary>>/binary, "]}"/utf8>>.
-file("src/kdleam/json.gleam", 128).
-spec encode_tag(kdleam@error:kdl_error_tag()) -> {binary(), binary()}.
encode_tag(Tag) ->
case Tag of
{unexpected_char, Ch} ->
{<<"UnexpectedChar"/utf8>>, encode_string(Ch)};
{disallowed_code_point, Ch@1} ->
{<<"DisallowedCodePoint"/utf8>>, encode_string(Ch@1)};
unexpected_eof ->
{<<"UnexpectedEof"/utf8>>, <<"null"/utf8>>};
invalid_escape ->
{<<"InvalidEscape"/utf8>>, <<"null"/utf8>>};
invalid_unicode_escape ->
{<<"InvalidUnicodeEscape"/utf8>>, <<"null"/utf8>>};
invalid_number ->
{<<"InvalidNumber"/utf8>>, <<"null"/utf8>>};
bare_keyword ->
{<<"BareKeyword"/utf8>>, <<"null"/utf8>>};
unmatched_block_comment_end ->
{<<"UnmatchedBlockCommentEnd"/utf8>>, <<"null"/utf8>>};
unclosed_block_comment ->
{<<"UnclosedBlockComment"/utf8>>, <<"null"/utf8>>};
unclosed_string ->
{<<"UnclosedString"/utf8>>, <<"null"/utf8>>};
inconsistent_indentation ->
{<<"InconsistentIndentation"/utf8>>, <<"null"/utf8>>};
invalid_slashdash ->
{<<"InvalidSlashdash"/utf8>>, <<"null"/utf8>>}
end.
-file("src/kdleam/json.gleam", 30).
?DOC(" エラーを行、列、タグ、任意の文字を持つ JSON 文字列へ変換する。\n").
-spec error_to_json(kdleam@error:kdl_error()) -> binary().
error_to_json(Error) ->
{kdl_error, Line, Col, Kind} = Error,
{kdl_error_kind, Tag} = Kind,
{Tag_name, Char} = encode_tag(Tag),
<<<<<<<<<<<<<<<<"{\"line\":"/utf8, (erlang:integer_to_binary(Line))/binary>>/binary,
",\"col\":"/utf8>>/binary,
(erlang:integer_to_binary(Col))/binary>>/binary,
",\"tag\":"/utf8>>/binary,
(encode_string(Tag_name))/binary>>/binary,
",\"char\":"/utf8>>/binary,
Char/binary>>/binary,
"}"/utf8>>.