Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:25
erlang
otp_src_25.3.2.9-lib-stdlib-json-compat.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File otp_src_25.3.2.9-lib-stdlib-json-compat.patch of Package erlang
diff -Ndurp otp_src_25.3.2.9/lib/stdlib/src/json.erl otp_src_25.3.2.9-lib-stdlib-json-compat/lib/stdlib/src/json.erl --- otp_src_25.3.2.9/lib/stdlib/src/json.erl 2024-03-10 02:58:14.763171530 +0200 +++ otp_src_25.3.2.9-lib-stdlib-json-compat/lib/stdlib/src/json.erl 2024-03-10 02:59:54.741050199 +0200 @@ -19,16 +19,6 @@ %% % @format %% -module(json). --moduledoc """ -A library for encoding and decoding JSON. - -This module implements [EEP68](https://github.com/erlang/eep/blob/master/eeps/eep-0068.md). - -Both encoder and decoder fully conform to -[RFC 8259](https://tools.ietf.org/html/rfc8259) and -[ECMA 404](https://ecma-international.org/publications-and-standards/standards/ecma-404/) -standards. The decoder is tested using [JSONTestSuite](https://github.com/nst/JSONTestSuite). -""". -dialyzer(no_improper_lists). @@ -89,11 +79,8 @@ standards. The decoder is tested using [ %% Encoding implementation %% --type encoder() :: fun((dynamic(), encoder()) -> iodata()). +-type encoder() :: fun((any(), encoder()) -> iodata()). --doc """ -Simple JSON value encodeable with `json:encode/1`. -""". -type encode_value() :: integer() | float() @@ -106,76 +93,18 @@ Simple JSON value encodeable with `json: -type encode_map(Value) :: #{binary() | atom() | integer() => Value}. --doc """ -Generates JSON corresponding to `Term`. - -Supports basic data mapping: - -| **Erlang** | **JSON** | -|------------------------|----------| -| `integer() \| float()` | Number | -| `true \| false ` | Boolean | -| `null` | Null | -| `binary()` | String | -| `atom()` | String | -| `list()` | Array | -| `#{binary() => _}` | Object | -| `#{atom() => _}` | Object | -| `#{integer() => _}` | Object | - -This is equivalent to `encode(Term, fun json:encode_value/2)`. - -## Examples - -```erlang -> iolist_to_binary(json:encode(#{foo => <<"bar">>})). -<<"{\"foo\":\"bar\"}">> -``` -""". --doc(#{since => <<"OTP 27.0">>}). -spec encode(encode_value()) -> iodata(). encode(Term) -> encode(Term, fun do_encode/2). --doc """ -Generates JSON corresponding to `Term`. - -Can be customised with the `Encoder` callback. -The callback will be recursively called for all the data -to be encoded and is expected to return the corresponding -encoded JSON as iodata. - -Various `encode_*` functions in this module can be used -to help in constructing such callbacks. - -## Examples - -An encoder that uses a heuristic to differentiate object-like -lists of key-value pairs from plain lists: - -```erlang -> encoder([{_, _} | _] = Value, Encode) -> json:encode_key_value_list(Value, Encode); -> encoder(Other, Encode) -> json:encode_value(Other, Encode). -> custom_encode(Value) -> json:encode(Value, fun(Value, Encode) -> encoder(Value, Encode) end). -> iolist_to_binary(custom_encode([{a, []}, {b, 1}])). -<<"{\"a\":[],\"b\":1}">> -``` -""". --doc(#{since => <<"OTP 27.0">>}). --spec encode(dynamic(), encoder()) -> iodata(). +-spec encode(any(), encoder()) -> iodata(). encode(Term, Encoder) when is_function(Encoder, 2) -> Encoder(Term, Encoder). --doc """ -Default encoder used by `json:encode/1`. - -Recursively calls `Encode` on all the values in `Value`. -""". --spec encode_value(dynamic(), encoder()) -> iodata(). --doc(#{since => <<"OTP 27.0">>}). +-spec encode_value(any(), encoder()) -> iodata(). encode_value(Value, Encode) -> do_encode(Value, Encode). --spec do_encode(dynamic(), encoder()) -> iodata(). +-spec do_encode(any(), encoder()) -> iodata(). do_encode(Value, Encode) when is_atom(Value) -> encode_atom(Value, Encode); do_encode(Value, _Encode) when is_binary(Value) -> @@ -191,39 +120,18 @@ do_encode(Value, Encode) when is_map(Val do_encode(Other, _Encode) -> error({unsupported_type, Other}). --doc """ -Default encoder for atoms used by `json:encode/1`. - -Encodes the atom `null` as JSON `null`, -atoms `true` and `false` as JSON booleans, -and everything else as JSON strings calling the `Encode` -callback with the corresponding binary. -""". -spec encode_atom(atom(), encoder()) -> iodata(). --doc(#{since => <<"OTP 27.0">>}). encode_atom(null, _Encode) -> <<"null">>; encode_atom(true, _Encode) -> <<"true">>; encode_atom(false, _Encode) -> <<"false">>; encode_atom(Other, Encode) -> Encode(atom_to_binary(Other, utf8), Encode). --doc """ -Default encoder for integers as JSON numbers used by `json:encode/1`. -""". --doc(#{since => <<"OTP 27.0">>}). -spec encode_integer(integer()) -> iodata(). encode_integer(Integer) -> integer_to_binary(Integer). --doc """ -Default encoder for floats as JSON numbers used by `json:encode/1`. -""". --doc(#{since => <<"OTP 27.0">>}). -spec encode_float(float()) -> iodata(). encode_float(Float) -> float_to_binary(Float, [short]). --doc """ -Default encoder for lists as JSON arrays used by `json:encode/1`. -""". --doc(#{since => <<"OTP 27.0">>}). -spec encode_list(list(), encoder()) -> iodata(). encode_list(List, Encode) when is_list(List) -> do_encode_list(List, Encode). @@ -236,57 +144,21 @@ do_encode_list([First | Rest], Encode) w list_loop([], _Encode) -> "]"; list_loop([Elem | Rest], Encode) -> [$,, Encode(Elem, Encode) | list_loop(Rest, Encode)]. --doc """ -Default encoder for maps as JSON objects used by `json:encode/1`. - -Accepts maps with atom, binary, integer, or float keys. -""". --doc(#{since => <<"OTP 27.0">>}). --spec encode_map(encode_map(dynamic()), encoder()) -> iodata(). +-spec encode_map(encode_map(any()), encoder()) -> iodata(). encode_map(Map, Encode) when is_map(Map) -> do_encode_map(Map, Encode). do_encode_map(Map, Encode) when is_function(Encode, 2) -> - encode_object([[$,, key(Key, Encode), $: | Encode(Value, Encode)] || Key := Value <- Map]). - --doc """ -Encoder for maps as JSON objects. - -Accepts maps with atom, binary, integer, or float keys. -Verifies that no duplicate keys will be produced in the -resulting JSON object. - -## Errors + encode_object([[$,, key(Key, Encode), $:|Encode(Value, Encode)] || {Key, Value} <- maps:to_list(Map)]). -Raises `error({duplicate_key, Key})` if there are duplicates. -""". --doc(#{since => <<"OTP 27.0">>}). -spec encode_map_checked(map(), encoder()) -> iodata(). encode_map_checked(Map, Encode) -> do_encode_checked(maps:to_list(Map), Encode). --doc """ -Encoder for lists of key-value pairs as JSON objects. - -Accepts lists with atom, binary, integer, or float keys. -""". --doc(#{since => <<"OTP 27.0">>}). -spec encode_key_value_list([{term(), term()}], encoder()) -> iodata(). encode_key_value_list(List, Encode) when is_function(Encode, 2) -> encode_object([[$,, key(Key, Encode), $: | Encode(Value, Encode)] || {Key, Value} <- List]). --doc """ -Encoder for lists of key-value pairs as JSON objects. - -Accepts lists with atom, binary, integer, or float keys. -Verifies that no duplicate keys will be produced in the -resulting JSON object. - -## Errors - -Raises `error({duplicate_key, Key})` if there are duplicates. -""". --doc(#{since => <<"OTP 27.0">>}). -spec encode_key_value_list_checked([{term(), term()}], encoder()) -> iodata(). encode_key_value_list_checked(List, Encode) -> do_encode_checked(List, Encode). @@ -318,30 +190,10 @@ key(Key, _Encode) when is_float(Key) -> encode_object([]) -> <<"{}">>; encode_object([[_Comma | Entry] | Rest]) -> ["{", Entry, Rest, "}"]. --doc """ -Default encoder for binaries as JSON strings used by `json:encode/1`. - -## Errors - -* `error(unexpected_end)` if the binary contains incomplete UTF-8 sequences. -* `error({invalid_byte, Byte})` if the binary contains invalid UTF-8 sequences. -""". --doc(#{since => <<"OTP 27.0">>}). -spec encode_binary(binary()) -> iodata(). encode_binary(Bin) when is_binary(Bin) -> escape_binary(Bin). --doc """ -Encoder for binaries as JSON strings producing pure-ASCII JSON. - -For any non-ASCII unicode character, a corresponding `\\uXXXX` sequence is used. - -## Errors - -* `error(unexpected_end)` if the binary contains incomplete UTF-8 sequences. -* `error({invalid_byte, Byte})` if the binary contains invalid UTF-8 sequences. -""". --doc(#{since => <<"OTP 27.0">>}). -spec encode_binary_escape_all(binary()) -> iodata(). encode_binary_escape_all(Bin) when is_binary(Bin) -> escape_all(Bin). @@ -541,13 +393,13 @@ error_info(Skip) -> -define(ARRAY, array). -define(OBJECT, object). --type from_binary_fun() :: fun((binary()) -> dynamic()). --type array_start_fun() :: fun((Acc :: dynamic()) -> ArrayAcc :: dynamic()). --type array_push_fun() :: fun((Value :: dynamic(), Acc :: dynamic()) -> NewAcc :: dynamic()). --type array_finish_fun() :: fun((ArrayAcc :: dynamic(), OldAcc :: dynamic()) -> {dynamic(), dynamic()}). --type object_start_fun() :: fun((Acc :: dynamic()) -> ObjectAcc :: dynamic()). --type object_push_fun() :: fun((Key :: dynamic(), Value :: dynamic(), Acc :: dynamic()) -> NewAcc :: dynamic()). --type object_finish_fun() :: fun((ObjectAcc :: dynamic(), OldAcc :: dynamic()) -> {dynamic(), dynamic()}). +-type from_binary_fun() :: fun((binary()) -> any()). +-type array_start_fun() :: fun((Acc :: any()) -> ArrayAcc :: any()). +-type array_push_fun() :: fun((Value :: any(), Acc :: any()) -> NewAcc :: any()). +-type array_finish_fun() :: fun((ArrayAcc :: any(), OldAcc :: any()) -> {any(), any()}). +-type object_start_fun() :: fun((Acc :: any()) -> ObjectAcc :: any()). +-type object_push_fun() :: fun((Key :: any(), Value :: any(), Acc :: any()) -> NewAcc :: any()). +-type object_finish_fun() :: fun((ObjectAcc :: any(), OldAcc :: any()) -> {any(), any()}). -type decoders() :: #{ array_start => array_start_fun(), @@ -575,7 +427,7 @@ error_info(Skip) -> null = null :: term() }). --type acc() :: dynamic(). +-type acc() :: any(). -type stack() :: [?ARRAY | ?OBJECT | binary() | acc()]. -type decode() :: #decode{}. @@ -590,33 +442,6 @@ error_info(Skip) -> | list(decode_value()) | #{binary() => decode_value()}. --doc """ -Parses a JSON value from `Binary`. - -Supports basic data mapping: - -| **JSON** | **Erlang** | -|----------|------------------------| -| Number | `integer() \| float()` | -| Boolean | `true \| false` | -| Null | `null` | -| String | `binary()` | -| Object | `#{binary() => _}` | - -## Errors - -* `error(unexpected_end)` if `Binary` contains incomplete JSON value -* `error({invalid_byte, Byte})` if `Binary` contains unexpected byte or invalid UTF-8 byte -* `error({invalid_sequence, Bytes})` if `Binary` contains invalid UTF-8 escape - -## Example - -```erlang -> json:decode(<<"{\"foo\": 1}">>). -#{<<"foo">> => 1} -``` -""". --doc(#{since => <<"OTP 27.0">>}). -spec decode(binary()) -> decode_value(). decode(Binary) when is_binary(Binary) -> case value(Binary, Binary, 0, ok, [], #decode{}) of @@ -632,51 +457,8 @@ decode(Binary) when is_binary(Binary) -> error(unexpected_end) end. --doc """ -Parses a JSON value from `Binary`. - -Similar to `decode/1` except the decoding process -can be customized with the callbacks specified in -`Decoders`. The callbacks will use the `Acc` value -as the initial accumulator. - -Any leftover, unparsed data in `Binary` will be returned. - -## Default callbacks - -All callbacks are optional. If not provided, they will fall back to -implementations used by the `decode/1` function: - -* for `array_start`: `fun(_) -> [] end` -* for `array_push`: `fun(Elem, Acc) -> [Elem | Acc] end` -* for `array_finish`: `fun(Acc, OldAcc) -> {lists:reverse(Acc), OldAcc} end` -* for `object_start`: `fun(_) -> [] end` -* for `object_push`: `fun(Key, Value, Acc) -> [{Key, Value} | Acc] end` -* for `object_finish`: `fun(Acc, OldAcc) -> {maps:from_list(Acc), OldAcc} end` -* for `float`: `fun erlang:binary_to_float/1` -* for `integer`: `fun erlang:binary_to_integer/1` -* for `string`: `fun (Value) -> Value end` -* for `null`: the atom `null` - -## Errors - -* `error({invalid_byte, Byte})` if `Binary` contains unexpected byte or invalid UTF-8 byte -* `error({invalid_sequence, Bytes})` if `Binary` contains invalid UTF-8 escape -* `error(unexpected_end)` if `Binary` contains incomplete JSON value - -## Example - -Decoding object keys as atoms: - -```erlang -> Push = fun(Key, Value, Acc) -> [{binary_to_existing_atom(Key), Value} | Acc] end. -> json:decode(<<"{\"foo\": 1}">>, ok, #{object_push => Push}). -{#{foo => 1},ok,<<>>} -``` -""". --doc(#{since => <<"OTP 27.0">>}). --spec decode(binary(), dynamic(), decoders()) -> - {Result :: dynamic(), Acc :: dynamic(), binary()}. +-spec decode(binary(), any(), decoders()) -> + {Result :: any(), Acc :: any(), binary()}. decode(Binary, Acc0, Decoders) when is_binary(Binary) -> Decode = maps:fold(fun parse_decoder/3, #decode{}, Decoders), case value(Binary, Binary, 0, Acc0, [], Decode) of @@ -690,40 +472,14 @@ decode(Binary, Acc0, Decoders) when is_b Result end. --doc """ -Begin parsing a stream of bytes of a JSON value. - -Similar to `decode/3` but returns when a complete JSON value can be parsed or -returns `{continue, State}` for incomplete data, -the `State` can be fed to the `decode_continue/2` function when more data is available. -""". --doc(#{since => <<"OTP 27.0">>}). --spec decode_start(binary(), dynamic(), decoders()) -> - {Result :: dynamic(), Acc :: dynamic(), binary()} | {continue, continuation_state()}. +-spec decode_start(binary(), any(), decoders()) -> + {Result :: any(), Acc :: any(), binary()} | {continue, continuation_state()}. decode_start(Binary, Acc, Decoders) when is_binary(Binary) -> Decode = maps:fold(fun parse_decoder/3, #decode{}, Decoders), value(Binary, Binary, 0, Acc, [], Decode). --doc """ -Continue parsing a stream of bytes of a JSON value. - -Similar to `decode_start/3`, if the function returns `{continue, State}` and -there is no more data, use `end_of_input` instead of a binary. - -```erlang -> {continue, State} = json:decode_start(<<"{\"foo\":">>, ok, #{}). -> json:decode_continue(<<"1}">>, State). -{#{foo => 1},ok,<<>>} -``` -```erlang -> {continue, State} = json:decode_start(<<"123">>, ok, #{}). -> json:decode_continue(end_of_input, State). -{123,ok,<<>>} -``` -""". --doc(#{since => <<"OTP 27.0">>}). -spec decode_continue(binary() | end_of_input, Opaque::term()) -> - {Result :: dynamic(), Acc :: dynamic(), binary()} | {continue, continuation_state()}. + {Result :: any(), Acc :: any(), binary()} | {continue, continuation_state()}. decode_continue(end_of_input, State) -> case State of {_, Acc, [], _Decode, {number, Val}} -> @@ -920,7 +676,7 @@ string_ascii(Binary, Original, Skip, Acc string(Other, Original, Skip, Acc, Stack, Decode, Len) end. --spec string(binary(), binary(), integer(), acc(), stack(), decode(), integer()) -> dynamic(). +-spec string(binary(), binary(), integer(), acc(), stack(), decode(), integer()) -> any(). string(<<Byte, Rest/bits>>, Orig, Skip, Acc, Stack, Decode, Len) when ?is_ascii_plain(Byte) -> string(Rest, Orig, Skip, Acc, Stack, Decode, Len + 1); string(<<$\\, Rest/bits>>, Orig, Skip, Acc, Stack, Decode, Len) -> @@ -963,7 +719,7 @@ string_ascii(Binary, Original, Skip, Acc string(Other, Original, Skip, Acc, Stack, Decode, Start, Len, SAcc) end. --spec string(binary(), binary(), integer(), acc(), stack(), decode(), integer(), integer(), binary()) -> dynamic(). +-spec string(binary(), binary(), integer(), acc(), stack(), decode(), integer(), integer(), binary()) -> any(). string(<<Byte, Rest/bits>>, Orig, Skip, Acc, Stack, Decode, Start, Len, SAcc) when ?is_ascii_plain(Byte) -> string(Rest, Orig, Skip, Acc, Stack, Decode, Start, Len + 1, SAcc); string(<<$\\, Rest/bits>>, Orig, Skip, Acc, Stack, Decode, Start, Len, SAcc) ->
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor