Packages
oaspec
0.4.0
0.68.0
0.67.0
0.66.0
0.65.0
0.64.0
0.63.0
0.62.0
0.61.0
0.60.0
0.59.0
0.58.1
0.58.0
0.57.0
0.56.0
0.55.0
0.54.0
0.53.0
0.52.0
0.51.0
0.50.0
0.49.0
0.48.0
0.47.0
0.46.0
0.45.0
0.44.0
0.43.0
0.42.0
0.41.0
0.40.0
0.39.0
0.38.0
0.37.0
0.36.0
0.35.0
0.34.0
0.33.0
0.32.0
0.31.0
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.0
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.0
0.9.0
0.8.0
0.7.0
0.6.3
0.6.1
0.6.0
0.5.0
0.4.0
0.3.0
0.1.3
Generate Gleam code from OpenAPI 3.x specifications
Current section
Files
Jump to
Current section
Files
src/oaspec@openapi@parser.erl
-module(oaspec@openapi@parser).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/oaspec/openapi/parser.gleam").
-export([parse_error_to_string/1, parse_schema_object/1, parse_schema_ref/1, parse_string/1, parse_file/1]).
-export_type([parse_error/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type parse_error() :: {file_error, binary()} |
{yaml_error, binary()} |
{missing_field, binary(), binary()} |
{invalid_value, binary(), binary()}.
-file("src/oaspec/openapi/parser.gleam", 93).
?DOC(" Parse the info object.\n").
-spec parse_info(yay:node_()) -> {ok, oaspec@openapi@spec:info()} |
{error, parse_error()}.
parse_info(Root) ->
gleam@result:'try'(
begin
_pipe = yay:select_sugar(Root, <<"info"/utf8>>),
gleam@result:map_error(
_pipe,
fun(_) -> {missing_field, <<""/utf8>>, <<"info"/utf8>>} end
)
end,
fun(Info_node) ->
gleam@result:'try'(
begin
_pipe@1 = yay:extract_string(Info_node, <<"title"/utf8>>),
gleam@result:map_error(
_pipe@1,
fun(_) ->
{missing_field, <<"info"/utf8>>, <<"title"/utf8>>}
end
)
end,
fun(Title) ->
gleam@result:'try'(
begin
_pipe@2 = yay:extract_string(
Info_node,
<<"version"/utf8>>
),
gleam@result:map_error(
_pipe@2,
fun(_) ->
{missing_field,
<<"info"/utf8>>,
<<"version"/utf8>>}
end
)
end,
fun(Version) ->
Description = begin
_pipe@3 = yay:extract_optional_string(
Info_node,
<<"description"/utf8>>
),
gleam@result:unwrap(_pipe@3, none)
end,
{ok, {info, Title, Description, Version}}
end
)
end
)
end
).
-file("src/oaspec/openapi/parser.gleam", 125).
?DOC(" Parse a single server object.\n").
-spec parse_server(yay:node_()) -> {ok, oaspec@openapi@spec:server()} |
{error, parse_error()}.
parse_server(Node) ->
gleam@result:'try'(
begin
_pipe = yay:extract_string(Node, <<"url"/utf8>>),
gleam@result:map_error(
_pipe,
fun(_) ->
{missing_field, <<"servers"/utf8>>, <<"url"/utf8>>}
end
)
end,
fun(Url) ->
Description = begin
_pipe@1 = yay:extract_optional_string(
Node,
<<"description"/utf8>>
),
gleam@result:unwrap(_pipe@1, none)
end,
{ok, {server, Url, Description}}
end
).
-file("src/oaspec/openapi/parser.gleam", 117).
?DOC(" Parse servers array.\n").
-spec parse_servers(yay:node_()) -> {ok, list(oaspec@openapi@spec:server())} |
{error, parse_error()}.
parse_servers(Root) ->
case yay:select_sugar(Root, <<"servers"/utf8>>) of
{ok, {node_seq, Items}} ->
gleam@list:try_map(Items, fun parse_server/1);
_ ->
{ok, []}
end.
-file("src/oaspec/openapi/parser.gleam", 448).
?DOC(" Resolve a $ref for a parameter by looking it up in components.\n").
-spec resolve_parameter_ref(
binary(),
gleam@option:option(oaspec@openapi@spec:components())
) -> {ok, oaspec@openapi@spec:parameter()} | {error, parse_error()}.
resolve_parameter_ref(Ref_str, Components) ->
Ref_name = begin
_pipe = Ref_str,
_pipe@1 = gleam@string:split(_pipe, <<"/"/utf8>>),
_pipe@2 = gleam@list:last(_pipe@1),
gleam@result:unwrap(_pipe@2, <<"unknown"/utf8>>)
end,
case Components of
{some, Comps} ->
case gleam_stdlib:map_get(erlang:element(3, Comps), Ref_name) of
{ok, Param} ->
{ok, Param};
{error, _} ->
{error,
{invalid_value,
<<"parameter.$ref"/utf8>>,
<<"Unresolved parameter reference: "/utf8,
Ref_str/binary>>}}
end;
none ->
{error,
{invalid_value,
<<"parameter.$ref"/utf8>>,
<<"No components to resolve reference: "/utf8,
Ref_str/binary>>}}
end.
-file("src/oaspec/openapi/parser.gleam", 477).
?DOC(" Resolve a $ref for a request body by looking it up in components.\n").
-spec resolve_request_body_ref(
binary(),
gleam@option:option(oaspec@openapi@spec:components())
) -> {ok, oaspec@openapi@spec:request_body()} | {error, parse_error()}.
resolve_request_body_ref(Ref_str, Components) ->
Ref_name = begin
_pipe = Ref_str,
_pipe@1 = gleam@string:split(_pipe, <<"/"/utf8>>),
_pipe@2 = gleam@list:last(_pipe@1),
gleam@result:unwrap(_pipe@2, <<"unknown"/utf8>>)
end,
case Components of
{some, Comps} ->
case gleam_stdlib:map_get(erlang:element(4, Comps), Ref_name) of
{ok, Rb} ->
{ok, Rb};
{error, _} ->
{error,
{invalid_value,
<<"requestBody.$ref"/utf8>>,
<<"Unresolved requestBody reference: "/utf8,
Ref_str/binary>>}}
end;
none ->
{error,
{invalid_value,
<<"requestBody.$ref"/utf8>>,
<<"No components to resolve reference: "/utf8,
Ref_str/binary>>}}
end.
-file("src/oaspec/openapi/parser.gleam", 506).
?DOC(" Resolve a $ref for a response by looking it up in components.\n").
-spec resolve_response_ref(
binary(),
gleam@option:option(oaspec@openapi@spec:components())
) -> {ok, oaspec@openapi@spec:response()} | {error, parse_error()}.
resolve_response_ref(Ref_str, Components) ->
Ref_name = begin
_pipe = Ref_str,
_pipe@1 = gleam@string:split(_pipe, <<"/"/utf8>>),
_pipe@2 = gleam@list:last(_pipe@1),
gleam@result:unwrap(_pipe@2, <<"unknown"/utf8>>)
end,
case Components of
{some, Comps} ->
case gleam_stdlib:map_get(erlang:element(5, Comps), Ref_name) of
{ok, Resp} ->
{ok, Resp};
{error, _} ->
{error,
{invalid_value,
<<"response.$ref"/utf8>>,
<<"Unresolved response reference: "/utf8,
Ref_str/binary>>}}
end;
none ->
{error,
{invalid_value,
<<"response.$ref"/utf8>>,
<<"No components to resolve reference: "/utf8,
Ref_str/binary>>}}
end.
-file("src/oaspec/openapi/parser.gleam", 535).
?DOC(" Parse parameter location string.\n").
-spec parse_parameter_in(binary()) -> {ok, oaspec@openapi@spec:parameter_in()} |
{error, parse_error()}.
parse_parameter_in(Value) ->
case Value of
<<"path"/utf8>> ->
{ok, in_path};
<<"query"/utf8>> ->
{ok, in_query};
<<"header"/utf8>> ->
{ok, in_header};
<<"cookie"/utf8>> ->
{ok, in_cookie};
_ ->
{error,
{invalid_value,
<<"parameter.in"/utf8>>,
<<<<"Unknown parameter location: "/utf8, Value/binary>>/binary,
". Must be one of: path, query, header, cookie"/utf8>>}}
end.
-file("src/oaspec/openapi/parser.gleam", 956).
?DOC(" Parse discriminator from a node.\n").
-spec parse_discriminator(yay:node_()) -> {ok,
oaspec@openapi@schema:discriminator()} |
{error, parse_error()}.
parse_discriminator(Node) ->
gleam@result:'try'(
begin
_pipe = yay:select_sugar(Node, <<"discriminator"/utf8>>),
gleam@result:map_error(
_pipe,
fun(_) ->
{missing_field, <<"schema"/utf8>>, <<"discriminator"/utf8>>}
end
)
end,
fun(Disc_node) ->
gleam@result:'try'(
begin
_pipe@1 = yay:extract_string(
Disc_node,
<<"propertyName"/utf8>>
),
gleam@result:map_error(
_pipe@1,
fun(_) ->
{missing_field,
<<"discriminator"/utf8>>,
<<"propertyName"/utf8>>}
end
)
end,
fun(Property_name) ->
Mapping = case yay:extract_string_map(
Disc_node,
<<"mapping"/utf8>>
) of
{ok, M} ->
M;
_ ->
maps:new()
end,
{ok, {discriminator, Property_name, Mapping}}
end
)
end
).
-file("src/oaspec/openapi/parser.gleam", 980).
?DOC(" Convert a parse error to a human-readable string.\n").
-spec parse_error_to_string(parse_error()) -> binary().
parse_error_to_string(Error) ->
case Error of
{file_error, Detail} ->
Detail;
{yaml_error, Detail@1} ->
Detail@1;
{missing_field, Path, Field} ->
<<<<<<"Missing field '"/utf8, Field/binary>>/binary, "' at "/utf8>>/binary,
Path/binary>>;
{invalid_value, Path@1, Detail@2} ->
<<<<<<"Invalid value at "/utf8, Path@1/binary>>/binary, ": "/utf8>>/binary,
Detail@2/binary>>
end.
-file("src/oaspec/openapi/parser.gleam", 1014).
?DOC(" Parse a single security scheme.\n").
-spec parse_security_scheme(yay:node_()) -> {ok,
oaspec@openapi@spec:security_scheme()} |
{error, parse_error()}.
parse_security_scheme(Node) ->
gleam@result:'try'(
begin
_pipe = yay:extract_string(Node, <<"type"/utf8>>),
gleam@result:map_error(
_pipe,
fun(_) ->
{missing_field, <<"securityScheme"/utf8>>, <<"type"/utf8>>}
end
)
end,
fun(Type_str) -> case Type_str of
<<"apiKey"/utf8>> ->
gleam@result:'try'(
begin
_pipe@1 = yay:extract_string(Node, <<"name"/utf8>>),
gleam@result:map_error(
_pipe@1,
fun(_) ->
{missing_field,
<<"securityScheme.apiKey"/utf8>>,
<<"name"/utf8>>}
end
)
end,
fun(Name) ->
gleam@result:'try'(
begin
_pipe@2 = yay:extract_string(
Node,
<<"in"/utf8>>
),
gleam@result:map_error(
_pipe@2,
fun(_) ->
{missing_field,
<<"securityScheme.apiKey"/utf8>>,
<<"in"/utf8>>}
end
)
end,
fun(In_str) -> case In_str of
<<"header"/utf8>> ->
{ok, {api_key_scheme, Name, In_str}};
<<"query"/utf8>> ->
{ok, {api_key_scheme, Name, In_str}};
<<"cookie"/utf8>> ->
{ok, {api_key_scheme, Name, In_str}};
_ ->
{error,
{invalid_value,
<<"securityScheme.apiKey.in"/utf8>>,
<<<<"Only 'header', 'query' and 'cookie' are supported for apiKey. Got: '"/utf8,
In_str/binary>>/binary,
"'"/utf8>>}}
end end
)
end
);
<<"http"/utf8>> ->
gleam@result:'try'(
begin
_pipe@3 = yay:extract_string(
Node,
<<"scheme"/utf8>>
),
gleam@result:map_error(
_pipe@3,
fun(_) ->
{missing_field,
<<"securityScheme.http"/utf8>>,
<<"scheme"/utf8>>}
end
)
end,
fun(Scheme) ->
Bearer_format = begin
_pipe@4 = yay:extract_optional_string(
Node,
<<"bearerFormat"/utf8>>
),
gleam@result:unwrap(_pipe@4, none)
end,
{ok, {http_scheme, Scheme, Bearer_format}}
end
);
<<"oauth2"/utf8>> ->
Description = begin
_pipe@5 = yay:extract_optional_string(
Node,
<<"description"/utf8>>
),
gleam@result:unwrap(_pipe@5, none)
end,
{ok, {o_auth2_scheme, Description}};
_ ->
{error,
{invalid_value,
<<"securityScheme.type"/utf8>>,
<<"Unsupported security scheme type: "/utf8,
Type_str/binary>>}}
end end
).
-file("src/oaspec/openapi/parser.gleam", 993).
?DOC(
" Parse security schemes from components.\n"
" Returns Ok(empty dict) if the section is absent, Error if present but\n"
" malformed.\n"
).
-spec parse_security_schemes_map(yay:node_()) -> {ok,
gleam@dict:dict(binary(), oaspec@openapi@spec:security_scheme())} |
{error, parse_error()}.
parse_security_schemes_map(Components_node) ->
case yay:select_sugar(Components_node, <<"securitySchemes"/utf8>>) of
{ok, {node_map, Entries}} ->
gleam@list:try_fold(
Entries,
maps:new(),
fun(Acc, Entry) ->
{Key_node, Value_node} = Entry,
case Key_node of
{node_str, Name} ->
gleam@result:'try'(
parse_security_scheme(Value_node),
fun(Scheme) ->
{ok, gleam@dict:insert(Acc, Name, Scheme)}
end
);
_ ->
{ok, Acc}
end
end
);
_ ->
{ok, maps:new()}
end.
-file("src/oaspec/openapi/parser.gleam", 1114).
?DOC(
" Parse a single security requirement object.\n"
" Returns one SecurityRequirement whose schemes list contains all AND-ed\n"
" scheme refs. The outer list (caller) represents OR alternatives.\n"
).
-spec parse_security_requirement_object(yay:node_(), binary()) -> {ok,
oaspec@openapi@spec:security_requirement()} |
{error, parse_error()}.
parse_security_requirement_object(Node, Context) ->
case Node of
{node_map, Entries} ->
gleam@result:'try'(
gleam@list:try_map(
Entries,
fun(Entry) ->
{Key_node, Scopes_node} = Entry,
case Key_node of
{node_str, Scheme_name} ->
gleam@result:'try'(case Scopes_node of
{node_seq, Scope_items} ->
gleam@list:try_map(
Scope_items,
fun(S) -> case S of
{node_str, V} ->
{ok, V};
_ ->
{error,
{invalid_value,
<<<<Context/binary,
".security."/utf8>>/binary,
Scheme_name/binary>>,
<<"Scope must be a string"/utf8>>}}
end end
);
node_nil ->
{ok, []};
_ ->
{error,
{invalid_value,
<<<<Context/binary,
".security."/utf8>>/binary,
Scheme_name/binary>>,
<<"Scopes must be an array of strings"/utf8>>}}
end, fun(Scopes) ->
{ok,
{security_scheme_ref,
Scheme_name,
Scopes}}
end);
_ ->
{error,
{invalid_value,
<<Context/binary, ".security"/utf8>>,
<<"Security requirement key must be a string"/utf8>>}}
end
end
),
fun(Scheme_refs) ->
{ok, {security_requirement, Scheme_refs}}
end
);
_ ->
{error,
{invalid_value,
<<Context/binary, ".security"/utf8>>,
<<"Security requirement must be an object"/utf8>>}}
end.
-file("src/oaspec/openapi/parser.gleam", 1078).
?DOC(
" Parse top-level security requirements.\n"
" Returns Ok([]) if absent, Error if present but malformed.\n"
).
-spec parse_security_requirements(yay:node_(), binary()) -> {ok,
list(oaspec@openapi@spec:security_requirement())} |
{error, parse_error()}.
parse_security_requirements(Node, Context) ->
case yay:select_sugar(Node, <<"security"/utf8>>) of
{ok, {node_seq, Items}} ->
gleam@list:try_map(
Items,
fun(Item) ->
parse_security_requirement_object(Item, Context)
end
);
_ ->
{ok, []}
end.
-file("src/oaspec/openapi/parser.gleam", 1094).
?DOC(
" Parse operation-level security requirements.\n"
" Returns Ok(None) if absent (inherits top-level), Ok(Some([])) if explicitly\n"
" empty (opts out), Ok(Some([...])) if specified.\n"
).
-spec parse_optional_security_requirements(yay:node_(), binary()) -> {ok,
gleam@option:option(list(oaspec@openapi@spec:security_requirement()))} |
{error, parse_error()}.
parse_optional_security_requirements(Node, Context) ->
case yay:select_sugar(Node, <<"security"/utf8>>) of
{ok, {node_seq, Items}} ->
gleam@result:'try'(
gleam@list:try_map(
Items,
fun(Item) ->
parse_security_requirement_object(Item, Context)
end
),
fun(Reqs) -> {ok, {some, Reqs}} end
);
_ ->
{ok, none}
end.
-file("src/oaspec/openapi/parser.gleam", 1165).
?DOC(" Convert a YAML error to a string.\n").
-spec yaml_error_to_string(yay:yaml_error()) -> binary().
yaml_error_to_string(Error) ->
case Error of
unexpected_parsing_error ->
<<"Unexpected parsing error"/utf8>>;
{parsing_error, Msg, _} ->
Msg
end.
-file("src/oaspec/openapi/parser.gleam", 791).
?DOC(" Parse a schema object.\n").
-spec parse_schema_object(yay:node_()) -> {ok,
oaspec@openapi@schema:schema_object()} |
{error, parse_error()}.
parse_schema_object(Node) ->
Nullable = begin
_pipe = yay:extract_optional_bool(Node, <<"nullable"/utf8>>),
_pipe@1 = gleam@result:unwrap(_pipe, none),
gleam@option:unwrap(_pipe@1, false)
end,
Description = begin
_pipe@2 = yay:extract_optional_string(Node, <<"description"/utf8>>),
gleam@result:unwrap(_pipe@2, none)
end,
case yay:select_sugar(Node, <<"allOf"/utf8>>) of
{ok, {node_seq, Items}} ->
gleam@result:'try'(
gleam@list:try_map(Items, fun parse_schema_ref/1),
fun(Schemas) -> {ok, {all_of_schema, Description, Schemas}} end
);
_ ->
case yay:select_sugar(Node, <<"oneOf"/utf8>>) of
{ok, {node_seq, Items@1}} ->
gleam@result:'try'(
gleam@list:try_map(Items@1, fun parse_schema_ref/1),
fun(Schemas@1) ->
gleam@result:'try'(
case yay:select_sugar(
Node,
<<"discriminator"/utf8>>
) of
{ok, _} ->
gleam@result:'try'(
parse_discriminator(Node),
fun(D) -> {ok, {some, D}} end
);
{error, _} ->
{ok, none}
end,
fun(Discriminator) ->
{ok,
{one_of_schema,
Description,
Schemas@1,
Discriminator}}
end
)
end
);
_ ->
case yay:select_sugar(Node, <<"anyOf"/utf8>>) of
{ok, {node_seq, Items@2}} ->
gleam@result:'try'(
gleam@list:try_map(
Items@2,
fun parse_schema_ref/1
),
fun(Schemas@2) ->
{ok,
{any_of_schema, Description, Schemas@2}}
end
);
_ ->
parse_typed_schema(Node, Description, Nullable)
end
end
end.
-file("src/oaspec/openapi/parser.gleam", 835).
?DOC(" Parse a typed schema (string, integer, number, boolean, array, object).\n").
-spec parse_typed_schema(yay:node_(), gleam@option:option(binary()), boolean()) -> {ok,
oaspec@openapi@schema:schema_object()} |
{error, parse_error()}.
parse_typed_schema(Node, Description, Nullable) ->
Type_str = begin
_pipe = yay:extract_optional_string(Node, <<"type"/utf8>>),
_pipe@1 = gleam@result:unwrap(_pipe, none),
gleam@option:unwrap(_pipe@1, <<"object"/utf8>>)
end,
Format = begin
_pipe@2 = yay:extract_optional_string(Node, <<"format"/utf8>>),
gleam@result:unwrap(_pipe@2, none)
end,
case Type_str of
<<"string"/utf8>> ->
Enum_values = case yay:extract_string_list(Node, <<"enum"/utf8>>) of
{ok, Values} ->
Values;
_ ->
[]
end,
Min_length = begin
_pipe@3 = yay:extract_optional_int(Node, <<"minLength"/utf8>>),
gleam@result:unwrap(_pipe@3, none)
end,
Max_length = begin
_pipe@4 = yay:extract_optional_int(Node, <<"maxLength"/utf8>>),
gleam@result:unwrap(_pipe@4, none)
end,
Pattern = begin
_pipe@5 = yay:extract_optional_string(Node, <<"pattern"/utf8>>),
gleam@result:unwrap(_pipe@5, none)
end,
{ok,
{string_schema,
Description,
Format,
Enum_values,
Min_length,
Max_length,
Pattern,
Nullable}};
<<"integer"/utf8>> ->
Minimum = begin
_pipe@6 = yay:extract_optional_int(Node, <<"minimum"/utf8>>),
gleam@result:unwrap(_pipe@6, none)
end,
Maximum = begin
_pipe@7 = yay:extract_optional_int(Node, <<"maximum"/utf8>>),
gleam@result:unwrap(_pipe@7, none)
end,
{ok,
{integer_schema,
Description,
Format,
Minimum,
Maximum,
Nullable}};
<<"number"/utf8>> ->
Minimum@1 = begin
_pipe@8 = yay:extract_optional_float(Node, <<"minimum"/utf8>>),
gleam@result:unwrap(_pipe@8, none)
end,
Maximum@1 = begin
_pipe@9 = yay:extract_optional_float(Node, <<"maximum"/utf8>>),
gleam@result:unwrap(_pipe@9, none)
end,
{ok,
{number_schema,
Description,
Format,
Minimum@1,
Maximum@1,
Nullable}};
<<"boolean"/utf8>> ->
{ok, {boolean_schema, Description, Nullable}};
<<"array"/utf8>> ->
gleam@result:'try'(case yay:select_sugar(Node, <<"items"/utf8>>) of
{ok, Items_node} ->
parse_schema_ref(Items_node);
_ ->
{error,
{missing_field,
<<"schema(type=array)"/utf8>>,
<<"items"/utf8>>}}
end, fun(Items) ->
Min_items = begin
_pipe@10 = yay:extract_optional_int(
Node,
<<"minItems"/utf8>>
),
gleam@result:unwrap(_pipe@10, none)
end,
Max_items = begin
_pipe@11 = yay:extract_optional_int(
Node,
<<"maxItems"/utf8>>
),
gleam@result:unwrap(_pipe@11, none)
end,
{ok,
{array_schema,
Description,
Items,
Min_items,
Max_items,
Nullable}}
end);
_ ->
gleam@result:'try'(
parse_properties(Node),
fun(Properties) ->
Required = case yay:extract_string_list(
Node,
<<"required"/utf8>>
) of
{ok, R} ->
R;
_ ->
[]
end,
gleam@result:'try'(
case yay:select_sugar(
Node,
<<"additionalProperties"/utf8>>
) of
{ok, {node_bool, true}} ->
{ok, {none, true}};
{ok, {node_bool, false}} ->
{ok, {none, false}};
{ok, Ap_node} ->
gleam@result:'try'(
parse_schema_ref(Ap_node),
fun(Sr) -> {ok, {{some, Sr}, false}} end
);
_ ->
{ok, {none, false}}
end,
fun(_use0) ->
{Additional_properties,
Additional_properties_untyped} = _use0,
{ok,
{object_schema,
Description,
Properties,
Required,
Additional_properties,
Additional_properties_untyped,
Nullable}}
end
)
end
)
end.
-file("src/oaspec/openapi/parser.gleam", 935).
?DOC(" Parse properties map from an object schema.\n").
-spec parse_properties(yay:node_()) -> {ok,
gleam@dict:dict(binary(), oaspec@openapi@schema:schema_ref())} |
{error, parse_error()}.
parse_properties(Node) ->
case yay:select_sugar(Node, <<"properties"/utf8>>) of
{ok, {node_map, Entries}} ->
gleam@list:try_fold(
Entries,
maps:new(),
fun(Acc, Entry) ->
{Key_node, Value_node} = Entry,
case Key_node of
{node_str, Name} ->
gleam@result:'try'(
parse_schema_ref(Value_node),
fun(Schema_ref) ->
{ok,
gleam@dict:insert(Acc, Name, Schema_ref)}
end
);
_ ->
{ok, Acc}
end
end
);
_ ->
{ok, maps:new()}
end.
-file("src/oaspec/openapi/parser.gleam", 780).
?DOC(" Parse a schema reference (either $ref or inline schema).\n").
-spec parse_schema_ref(yay:node_()) -> {ok, oaspec@openapi@schema:schema_ref()} |
{error, parse_error()}.
parse_schema_ref(Node) ->
case yay:extract_optional_string(Node, <<"$ref"/utf8>>) of
{ok, {some, Ref}} ->
{ok, {reference, Ref}};
_ ->
gleam@result:'try'(
parse_schema_object(Node),
fun(Schema_obj) -> {ok, {inline, Schema_obj}} end
)
end.
-file("src/oaspec/openapi/parser.gleam", 369).
?DOC(" Parse a single parameter.\n").
-spec parse_parameter(
yay:node_(),
gleam@option:option(oaspec@openapi@spec:components())
) -> {ok, oaspec@openapi@spec:parameter()} | {error, parse_error()}.
parse_parameter(Node, Components) ->
case yay:extract_optional_string(Node, <<"$ref"/utf8>>) of
{ok, {some, Ref_str}} ->
resolve_parameter_ref(Ref_str, Components);
_ ->
gleam@result:'try'(
begin
_pipe = yay:extract_string(Node, <<"name"/utf8>>),
gleam@result:map_error(
_pipe,
fun(_) ->
{missing_field,
<<"parameter"/utf8>>,
<<"name"/utf8>>}
end
)
end,
fun(Name) ->
gleam@result:'try'(
begin
_pipe@1 = yay:extract_string(Node, <<"in"/utf8>>),
gleam@result:map_error(
_pipe@1,
fun(_) ->
{missing_field,
<<"parameter."/utf8, Name/binary>>,
<<"in"/utf8>>}
end
)
end,
fun(In_str) ->
gleam@result:'try'(
parse_parameter_in(In_str),
fun(In_) ->
Description = begin
_pipe@2 = yay:extract_optional_string(
Node,
<<"description"/utf8>>
),
gleam@result:unwrap(_pipe@2, none)
end,
Explicit_required = begin
_pipe@3 = yay:extract_optional_bool(
Node,
<<"required"/utf8>>
),
gleam@result:unwrap(_pipe@3, none)
end,
gleam@result:'try'(
case {In_, Explicit_required} of
{in_path, {some, false}} ->
{error,
{invalid_value,
<<"parameter."/utf8,
Name/binary>>,
<<"Path parameters must have required: true"/utf8>>}};
{in_path, _} ->
{ok, true};
{_, {some, V}} ->
{ok, V};
{_, none} ->
{ok, false}
end,
fun(Required) ->
Deprecated = begin
_pipe@4 = yay:extract_optional_bool(
Node,
<<"deprecated"/utf8>>
),
_pipe@5 = gleam@result:unwrap(
_pipe@4,
none
),
gleam@option:unwrap(
_pipe@5,
false
)
end,
gleam@result:'try'(
case yay:select_sugar(
Node,
<<"schema"/utf8>>
) of
{ok, Schema_node} ->
gleam@result:'try'(
parse_schema_ref(
Schema_node
),
fun(Sr) ->
{ok, {some, Sr}}
end
);
_ ->
{ok, none}
end,
fun(Param_schema) ->
Style = begin
_pipe@6 = yay:extract_optional_string(
Node,
<<"style"/utf8>>
),
gleam@result:unwrap(
_pipe@6,
none
)
end,
{ok,
{parameter,
Name,
In_,
Description,
Required,
Param_schema,
Style,
Deprecated}}
end
)
end
)
end
)
end
)
end
)
end.
-file("src/oaspec/openapi/parser.gleam", 357).
?DOC(" Parse parameters list from a node.\n").
-spec parse_parameters_list(
yay:node_(),
gleam@option:option(oaspec@openapi@spec:components())
) -> {ok, list(oaspec@openapi@spec:parameter())} | {error, parse_error()}.
parse_parameters_list(Node, Components) ->
case yay:select_sugar(Node, <<"parameters"/utf8>>) of
{ok, {node_seq, Items}} ->
gleam@list:try_map(
Items,
fun(Item) -> parse_parameter(Item, Components) end
);
_ ->
{ok, []}
end.
-file("src/oaspec/openapi/parser.gleam", 591).
?DOC(" Parse content map (media type -> schema).\n").
-spec parse_content(yay:node_(), binary()) -> {ok,
gleam@dict:dict(binary(), oaspec@openapi@spec:media_type())} |
{error, parse_error()}.
parse_content(Node, _) ->
case yay:select_sugar(Node, <<"content"/utf8>>) of
{ok, {node_map, Entries}} ->
gleam@list:try_fold(
Entries,
maps:new(),
fun(Acc, Entry) ->
{Key_node, Value_node} = Entry,
case Key_node of
{node_str, Media_type_name} ->
gleam@result:'try'(
case yay:select_sugar(
Value_node,
<<"schema"/utf8>>
) of
{ok, Schema_node} ->
gleam@result:'try'(
parse_schema_ref(Schema_node),
fun(Sr) -> {ok, {some, Sr}} end
);
_ ->
{ok, none}
end,
fun(Mt_schema) ->
{ok,
gleam@dict:insert(
Acc,
Media_type_name,
{media_type, Mt_schema}
)}
end
);
_ ->
{ok, Acc}
end
end
);
_ ->
{ok, maps:new()}
end.
-file("src/oaspec/openapi/parser.gleam", 572).
?DOC(" Parse a request body object.\n").
-spec parse_request_body(yay:node_(), binary()) -> {ok,
oaspec@openapi@spec:request_body()} |
{error, parse_error()}.
parse_request_body(Node, Context) ->
Description = begin
_pipe = yay:extract_optional_string(Node, <<"description"/utf8>>),
gleam@result:unwrap(_pipe, none)
end,
Required = begin
_pipe@1 = yay:extract_optional_bool(Node, <<"required"/utf8>>),
_pipe@2 = gleam@result:unwrap(_pipe@1, none),
gleam@option:unwrap(_pipe@2, false)
end,
gleam@result:'try'(
parse_content(Node, Context),
fun(Content) -> {ok, {request_body, Description, Content, Required}} end
).
-file("src/oaspec/openapi/parser.gleam", 552).
?DOC(" Parse requestBody from a node.\n").
-spec parse_request_body_at(
yay:node_(),
binary(),
gleam@option:option(oaspec@openapi@spec:components())
) -> {ok, oaspec@openapi@spec:request_body()} | {error, parse_error()}.
parse_request_body_at(Node, Context, Components) ->
gleam@result:'try'(
begin
_pipe = yay:select_sugar(Node, <<"requestBody"/utf8>>),
gleam@result:map_error(
_pipe,
fun(_) -> {missing_field, Context, <<"requestBody"/utf8>>} end
)
end,
fun(Rb_node) ->
case yay:extract_optional_string(Rb_node, <<"$ref"/utf8>>) of
{ok, {some, Ref_str}} ->
resolve_request_body_ref(Ref_str, Components);
_ ->
parse_request_body(Rb_node, Context)
end
end
).
-file("src/oaspec/openapi/parser.gleam", 330).
?DOC(
" Parse optional requestBody: Ok(None) if absent, Ok(Some(..)) if valid,\n"
" Error if present but malformed.\n"
).
-spec parse_optional_request_body(
yay:node_(),
binary(),
gleam@option:option(oaspec@openapi@spec:components())
) -> {ok, gleam@option:option(oaspec@openapi@spec:request_body())} |
{error, parse_error()}.
parse_optional_request_body(Node, Context, Components) ->
case yay:select_sugar(Node, <<"requestBody"/utf8>>) of
{ok, _} ->
gleam@result:'try'(
parse_request_body_at(Node, Context, Components),
fun(Rb) -> {ok, {some, Rb}} end
);
{error, _} ->
{ok, none}
end.
-file("src/oaspec/openapi/parser.gleam", 649).
?DOC(" Parse a single response object.\n").
-spec parse_response(
yay:node_(),
gleam@option:option(oaspec@openapi@spec:components())
) -> {ok, oaspec@openapi@spec:response()} | {error, parse_error()}.
parse_response(Node, Components) ->
case yay:extract_optional_string(Node, <<"$ref"/utf8>>) of
{ok, {some, Ref_str}} ->
resolve_response_ref(Ref_str, Components);
_ ->
Description = begin
_pipe = yay:extract_optional_string(
Node,
<<"description"/utf8>>
),
gleam@result:unwrap(_pipe, none)
end,
gleam@result:'try'(
parse_content(Node, <<"response"/utf8>>),
fun(Content) -> {ok, {response, Description, Content}} end
)
end.
-file("src/oaspec/openapi/parser.gleam", 621).
?DOC(" Parse responses object.\n").
-spec parse_responses(
yay:node_(),
binary(),
gleam@option:option(oaspec@openapi@spec:components())
) -> {ok, gleam@dict:dict(binary(), oaspec@openapi@spec:response())} |
{error, parse_error()}.
parse_responses(Node, _, Components) ->
case yay:select_sugar(Node, <<"responses"/utf8>>) of
{ok, {node_map, Entries}} ->
gleam@list:try_fold(
Entries,
maps:new(),
fun(Acc, Entry) ->
{Key_node, Value_node} = Entry,
case Key_node of
{node_str, Status_code} ->
gleam@result:'try'(
parse_response(Value_node, Components),
fun(Resp) ->
{ok,
gleam@dict:insert(
Acc,
Status_code,
Resp
)}
end
);
{node_int, Code} ->
gleam@result:'try'(
parse_response(Value_node, Components),
fun(Resp@1) ->
Code_str = gleam@string:inspect(Code),
{ok,
gleam@dict:insert(Acc, Code_str, Resp@1)}
end
);
_ ->
{ok, Acc}
end
end
);
_ ->
{ok, maps:new()}
end.
-file("src/oaspec/openapi/parser.gleam", 345).
?DOC(" Parse responses, requiring the field to be present.\n").
-spec parse_responses_required(
yay:node_(),
binary(),
gleam@option:option(oaspec@openapi@spec:components())
) -> {ok, gleam@dict:dict(binary(), oaspec@openapi@spec:response())} |
{error, parse_error()}.
parse_responses_required(Node, Context, Components) ->
case yay:select_sugar(Node, <<"responses"/utf8>>) of
{ok, _} ->
parse_responses(Node, Context, Components);
{error, _} ->
{error, {missing_field, Context, <<"responses"/utf8>>}}
end.
-file("src/oaspec/openapi/parser.gleam", 270).
?DOC(" Parse a single operation.\n").
-spec parse_operation(
yay:node_(),
binary(),
gleam@option:option(oaspec@openapi@spec:components())
) -> {ok, oaspec@openapi@spec:operation()} | {error, parse_error()}.
parse_operation(Node, Context, Components) ->
Operation_id = begin
_pipe = yay:extract_optional_string(Node, <<"operationId"/utf8>>),
gleam@result:unwrap(_pipe, none)
end,
Summary = begin
_pipe@1 = yay:extract_optional_string(Node, <<"summary"/utf8>>),
gleam@result:unwrap(_pipe@1, none)
end,
Description = begin
_pipe@2 = yay:extract_optional_string(Node, <<"description"/utf8>>),
gleam@result:unwrap(_pipe@2, none)
end,
Tags = case yay:extract_string_list(Node, <<"tags"/utf8>>) of
{ok, T} ->
T;
_ ->
[]
end,
Deprecated = begin
_pipe@3 = yay:extract_optional_bool(Node, <<"deprecated"/utf8>>),
_pipe@4 = gleam@result:unwrap(_pipe@3, none),
gleam@option:unwrap(_pipe@4, false)
end,
gleam@result:'try'(
parse_parameters_list(Node, Components),
fun(Parameters) ->
gleam@result:'try'(
parse_optional_request_body(Node, Context, Components),
fun(Request_body) ->
gleam@result:'try'(
parse_responses_required(Node, Context, Components),
fun(Responses) ->
gleam@result:'try'(
parse_optional_security_requirements(
Node,
Context
),
fun(Security) ->
{ok,
{operation,
Operation_id,
Summary,
Description,
Tags,
Parameters,
Request_body,
Responses,
Deprecated,
Security}}
end
)
end
)
end
)
end
).
-file("src/oaspec/openapi/parser.gleam", 254).
?DOC(" Parse an operation at a specific HTTP method key.\n").
-spec parse_operation_at(
yay:node_(),
binary(),
binary(),
oaspec@openapi@spec:http_method(),
gleam@option:option(oaspec@openapi@spec:components())
) -> {ok, oaspec@openapi@spec:operation()} | {error, parse_error()}.
parse_operation_at(Node, Method_key, Path, _, Components) ->
gleam@result:'try'(
begin
_pipe = yay:select_sugar(Node, Method_key),
gleam@result:map_error(
_pipe,
fun(_) -> {missing_field, Path, Method_key} end
)
end,
fun(Op_node) ->
parse_operation(
Op_node,
<<<<Path/binary, "."/utf8>>/binary, Method_key/binary>>,
Components
)
end
).
-file("src/oaspec/openapi/parser.gleam", 231).
?DOC(
" Parse an optional operation: Ok(None) if key absent, Ok(Some(..)) if valid,\n"
" Error if present but malformed.\n"
).
-spec parse_optional_operation(
yay:node_(),
binary(),
binary(),
oaspec@openapi@spec:http_method(),
gleam@option:option(oaspec@openapi@spec:components())
) -> {ok, gleam@option:option(oaspec@openapi@spec:operation())} |
{error, parse_error()}.
parse_optional_operation(Node, Method_key, Path, Method, Components) ->
case yay:select_sugar(Node, Method_key) of
{ok, _} ->
gleam@result:'try'(
parse_operation_at(Node, Method_key, Path, Method, Components),
fun(Op) -> {ok, {some, Op}} end
);
{error, _} ->
{ok, none}
end.
-file("src/oaspec/openapi/parser.gleam", 165).
?DOC(" Parse a single path item.\n").
-spec parse_path_item(
yay:node_(),
binary(),
gleam@option:option(oaspec@openapi@spec:components())
) -> {ok, oaspec@openapi@spec:path_item()} | {error, parse_error()}.
parse_path_item(Node, Path, Components) ->
Summary = begin
_pipe = yay:extract_optional_string(Node, <<"summary"/utf8>>),
gleam@result:unwrap(_pipe, none)
end,
Description = begin
_pipe@1 = yay:extract_optional_string(Node, <<"description"/utf8>>),
gleam@result:unwrap(_pipe@1, none)
end,
gleam@result:'try'(
parse_optional_operation(Node, <<"get"/utf8>>, Path, get, Components),
fun(Get) ->
gleam@result:'try'(
parse_optional_operation(
Node,
<<"post"/utf8>>,
Path,
post,
Components
),
fun(Post) ->
gleam@result:'try'(
parse_optional_operation(
Node,
<<"put"/utf8>>,
Path,
put,
Components
),
fun(Put) ->
gleam@result:'try'(
parse_optional_operation(
Node,
<<"delete"/utf8>>,
Path,
delete,
Components
),
fun(Delete) ->
gleam@result:'try'(
parse_optional_operation(
Node,
<<"patch"/utf8>>,
Path,
patch,
Components
),
fun(Patch) ->
gleam@result:'try'(
parse_parameters_list(
Node,
Components
),
fun(Parameters) ->
{ok,
{path_item,
Summary,
Description,
Get,
Post,
Put,
Delete,
Patch,
Parameters}}
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/oaspec/openapi/parser.gleam", 139).
?DOC(" Parse the paths object.\n").
-spec parse_paths(
yay:node_(),
gleam@option:option(oaspec@openapi@spec:components())
) -> {ok, gleam@dict:dict(binary(), oaspec@openapi@spec:path_item())} |
{error, parse_error()}.
parse_paths(Root, Components) ->
case yay:select_sugar(Root, <<"paths"/utf8>>) of
{ok, {node_map, Entries}} ->
gleam@list:try_fold(
Entries,
maps:new(),
fun(Acc, Entry) ->
{Key_node, Value_node} = Entry,
case Key_node of
{node_str, Path} ->
gleam@result:'try'(
parse_path_item(Value_node, Path, Components),
fun(Path_item) ->
{ok,
gleam@dict:insert(Acc, Path, Path_item)}
end
);
_ ->
{ok, Acc}
end
end
);
_ ->
{ok, maps:new()}
end.
-file("src/oaspec/openapi/parser.gleam", 691).
?DOC(" Parse the schemas map from components.\n").
-spec parse_schemas_map(yay:node_()) -> {ok,
gleam@dict:dict(binary(), oaspec@openapi@schema:schema_ref())} |
{error, parse_error()}.
parse_schemas_map(Components_node) ->
case yay:select_sugar(Components_node, <<"schemas"/utf8>>) of
{ok, {node_map, Entries}} ->
gleam@list:try_fold(
Entries,
maps:new(),
fun(Acc, Entry) ->
{Key_node, Value_node} = Entry,
case Key_node of
{node_str, Name} ->
gleam@result:'try'(
parse_schema_ref(Value_node),
fun(Schema_ref) ->
{ok,
gleam@dict:insert(Acc, Name, Schema_ref)}
end
);
_ ->
{ok, Acc}
end
end
);
_ ->
{ok, maps:new()}
end.
-file("src/oaspec/openapi/parser.gleam", 712).
?DOC(" Parse the parameters map from components.\n").
-spec parse_parameters_map(yay:node_()) -> {ok,
gleam@dict:dict(binary(), oaspec@openapi@spec:parameter())} |
{error, parse_error()}.
parse_parameters_map(Components_node) ->
case yay:select_sugar(Components_node, <<"parameters"/utf8>>) of
{ok, {node_map, Entries}} ->
gleam@list:try_fold(
Entries,
maps:new(),
fun(Acc, Entry) ->
{Key_node, Value_node} = Entry,
case Key_node of
{node_str, Name} ->
gleam@result:'try'(
parse_parameter(Value_node, none),
fun(Param) ->
{ok, gleam@dict:insert(Acc, Name, Param)}
end
);
_ ->
{ok, Acc}
end
end
);
_ ->
{ok, maps:new()}
end.
-file("src/oaspec/openapi/parser.gleam", 734).
?DOC(" Parse the requestBodies map from components.\n").
-spec parse_request_bodies_map(yay:node_()) -> {ok,
gleam@dict:dict(binary(), oaspec@openapi@spec:request_body())} |
{error, parse_error()}.
parse_request_bodies_map(Components_node) ->
case yay:select_sugar(Components_node, <<"requestBodies"/utf8>>) of
{ok, {node_map, Entries}} ->
gleam@list:try_fold(
Entries,
maps:new(),
fun(Acc, Entry) ->
{Key_node, Value_node} = Entry,
case Key_node of
{node_str, Name} ->
gleam@result:'try'(
parse_request_body(
Value_node,
<<"components.requestBodies."/utf8,
Name/binary>>
),
fun(Rb) ->
{ok, gleam@dict:insert(Acc, Name, Rb)}
end
);
_ ->
{ok, Acc}
end
end
);
_ ->
{ok, maps:new()}
end.
-file("src/oaspec/openapi/parser.gleam", 758).
?DOC(" Parse the responses map from components.\n").
-spec parse_responses_map(yay:node_()) -> {ok,
gleam@dict:dict(binary(), oaspec@openapi@spec:response())} |
{error, parse_error()}.
parse_responses_map(Components_node) ->
case yay:select_sugar(Components_node, <<"responses"/utf8>>) of
{ok, {node_map, Entries}} ->
gleam@list:try_fold(
Entries,
maps:new(),
fun(Acc, Entry) ->
{Key_node, Value_node} = Entry,
case Key_node of
{node_str, Name} ->
gleam@result:'try'(
parse_response(Value_node, none),
fun(Resp) ->
{ok, gleam@dict:insert(Acc, Name, Resp)}
end
);
_ ->
{ok, Acc}
end
end
);
_ ->
{ok, maps:new()}
end.
-file("src/oaspec/openapi/parser.gleam", 669).
?DOC(" Parse the components section.\n").
-spec parse_components(yay:node_()) -> {ok, oaspec@openapi@spec:components()} |
{error, parse_error()}.
parse_components(Root) ->
gleam@result:'try'(
begin
_pipe = yay:select_sugar(Root, <<"components"/utf8>>),
gleam@result:map_error(
_pipe,
fun(_) ->
{missing_field, <<""/utf8>>, <<"components"/utf8>>}
end
)
end,
fun(Components_node) ->
gleam@result:'try'(
parse_schemas_map(Components_node),
fun(Schemas) ->
gleam@result:'try'(
parse_parameters_map(Components_node),
fun(Parameters) ->
gleam@result:'try'(
parse_request_bodies_map(Components_node),
fun(Request_bodies) ->
gleam@result:'try'(
parse_responses_map(Components_node),
fun(Responses) ->
gleam@result:'try'(
parse_security_schemes_map(
Components_node
),
fun(Security_schemes) ->
{ok,
{components,
Schemas,
Parameters,
Request_bodies,
Responses,
Security_schemes}}
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/oaspec/openapi/parser.gleam", 80).
?DOC(
" Parse optional components section.\n"
" Returns Ok(None) if not present, Ok(Some(..)) if valid, Error if malformed.\n"
).
-spec parse_optional_components(yay:node_()) -> {ok,
gleam@option:option(oaspec@openapi@spec:components())} |
{error, parse_error()}.
parse_optional_components(Root) ->
case yay:select_sugar(Root, <<"components"/utf8>>) of
{ok, _} ->
gleam@result:'try'(
parse_components(Root),
fun(Comps) -> {ok, {some, Comps}} end
);
{error, _} ->
{ok, none}
end.
-file("src/oaspec/openapi/parser.gleam", 59).
?DOC(" Parse the root OpenAPI object.\n").
-spec parse_root(yay:node_()) -> {ok, oaspec@openapi@spec:open_api_spec()} |
{error, parse_error()}.
parse_root(Node) ->
gleam@result:'try'(
begin
_pipe = yay:extract_string(Node, <<"openapi"/utf8>>),
gleam@result:map_error(
_pipe,
fun(_) -> {missing_field, <<""/utf8>>, <<"openapi"/utf8>>} end
)
end,
fun(Openapi) ->
gleam@result:'try'(
parse_info(Node),
fun(Info) ->
gleam@result:'try'(
parse_optional_components(Node),
fun(Components) ->
gleam@result:'try'(
parse_paths(Node, Components),
fun(Paths) ->
gleam@result:'try'(
parse_servers(Node),
fun(Servers) ->
gleam@result:'try'(
parse_security_requirements(
Node,
<<""/utf8>>
),
fun(Security) ->
{ok,
{open_api_spec,
Openapi,
Info,
Paths,
Components,
Servers,
Security}}
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/oaspec/openapi/parser.gleam", 43).
?DOC(" Parse an OpenAPI spec from a YAML/JSON string.\n").
-spec parse_string(binary()) -> {ok, oaspec@openapi@spec:open_api_spec()} |
{error, parse_error()}.
parse_string(Content) ->
gleam@result:'try'(
begin
_pipe = yaml_ffi:parse_string(Content),
gleam@result:map_error(
_pipe,
fun(E) -> {yaml_error, yaml_error_to_string(E)} end
)
end,
fun(Docs) -> gleam@result:'try'(case Docs of
[First | _] ->
{ok, First};
[] ->
{error, {yaml_error, <<"Empty document"/utf8>>}}
end, fun(Doc) ->
Root = yay:document_root(Doc),
parse_root(Root)
end) end
).
-file("src/oaspec/openapi/parser.gleam", 31).
?DOC(
" Parse an OpenAPI spec from a file path.\n"
" Supports both YAML (.yaml, .yml) and JSON (.json) files.\n"
).
-spec parse_file(binary()) -> {ok, oaspec@openapi@spec:open_api_spec()} |
{error, parse_error()}.
parse_file(Path) ->
gleam@result:'try'(
begin
_pipe = simplifile:read(Path),
gleam@result:map_error(
_pipe,
fun(_) ->
{file_error, <<"Cannot read file: "/utf8, Path/binary>>}
end
)
end,
fun(Content) -> parse_string(Content) end
).