diff --git a/rebar.config b/rebar.config index e9d7f12..6dceb92 100644 --- a/rebar.config +++ b/rebar.config @@ -1,5 +1,5 @@ %%-*- mode: erlang -*- -{profiles, [{test, [{deps, [{ proper, "1.4.0"}]}]}]}. +{profiles, [{test, [{deps, [{jsx, "3.1.0"}, {rfc3339, "0.9.0"}, {proper, "1.4.0"}]}]}]}. {erl_opts, [ {platform_define, "^R[0-9]+", erlang_deprecated_types} %% , warn_export_all , warn_export_vars @@ -18,11 +18,6 @@ , undefined_function_calls , deprecated_function_calls ]}. -{ deps -, [ {jsx, "3.1.0"} - , {rfc3339, "0.9.0"} - ]}. - { project_plugins , [ {rebar3_lint, "3.2.6"} , {rebar3_proper, "0.12.1"} diff --git a/rebar.config.script b/rebar.config.script new file mode 100644 index 0000000..27f6df2 --- /dev/null +++ b/rebar.config.script @@ -0,0 +1,15 @@ +{Deps0, Config0} = case lists:keytake(deps, 1, CONFIG) of + false -> {[], CONFIG}; + {value, {deps, D}, Cfg} -> {D, Cfg} + end, + +Deps = case list_to_integer(erlang:system_info(otp_release)) of + N when N >= 27 -> + Deps0; + N when N >= 21 -> + [{jsx, "3.1.0"} | Deps0]; + _ -> + [{jsx, "3.1.0"}, {rfc3339, "0.9.0"} | Deps0] + end, + +[{deps, Deps} | Config0]. diff --git a/src/jesse.app.src b/src/jesse.app.src index 6c689e9..6aaca89 100644 --- a/src/jesse.app.src +++ b/src/jesse.app.src @@ -11,8 +11,6 @@ , public_key , ssl , inets - , jsx - , rfc3339 ]} , {env, [ {re_options, [unicode, ucp]} ]} diff --git a/src/jesse.app.src.script b/src/jesse.app.src.script new file mode 100644 index 0000000..520b446 --- /dev/null +++ b/src/jesse.app.src.script @@ -0,0 +1,19 @@ +[{application, jesse, Config}] = CONFIG, + +{Apps0, Config0} = case lists:keytake(applications, 1, Config) of + false -> + {[], CONFIG}; + {value, {applications, A}, Cfg} -> + {A, Cfg} + end, + +Apps = case list_to_integer(erlang:system_info(otp_release)) of + N when N >= 27 -> + Apps0; + N when N >= 21 -> + [jsx | Apps0]; + _ -> + [jsx, rfc3339 | Apps0] + end, + +[{application, jesse, [{applications, Apps} | Config]}]. diff --git a/src/jesse_cli.erl b/src/jesse_cli.erl index 9a0917c..d807084 100644 --- a/src/jesse_cli.erl +++ b/src/jesse_cli.erl @@ -75,7 +75,7 @@ run(Options, [Schema|_] = Schemata, [JsonInstance|JsonInstances]) -> undefined -> io:fwrite("~p\n\n", [Result]); true -> - io:fwrite("~s\n\n", [jsx:encode(Result)]) + io:fwrite("~s\n\n", [jesse_lib:json_encode(Result)]) end, case JesseResult of {ok, _} -> @@ -86,11 +86,12 @@ run(Options, [Schema|_] = Schemata, [JsonInstance|JsonInstances]) -> halt(1) end. + jesse_run(JsonInstance, Schema, Schemata) -> {ok, _} = application:ensure_all_started(jesse), ok = add_schemata(Schemata), {ok, JsonInstanceBinary} = file:read_file(JsonInstance), - JsonInstanceJsx = jsx:decode(JsonInstanceBinary, [{return_maps, false}]), + JsonInstanceJsx = jesse_lib:json_decode(JsonInstanceBinary), jesse:validate( Schema , JsonInstanceJsx ). @@ -99,7 +100,7 @@ add_schemata([]) -> ok; add_schemata([SchemaFile|Rest]) -> {ok, SchemaBin} = file:read_file(SchemaFile), - Schema0 = jsx:decode(SchemaBin, [{return_maps, false}]), + Schema0 = jesse_lib:json_decode(SchemaBin), Schema = maybe_fill_schema_id(SchemaFile, Schema0), ok = jesse:add_schema(SchemaFile, Schema), add_schemata(Rest). diff --git a/src/jesse_database.erl b/src/jesse_database.erl index f4a3e94..bec09f1 100644 --- a/src/jesse_database.erl +++ b/src/jesse_database.erl @@ -307,7 +307,7 @@ add_file_uri(Key0) -> "file://" ++ File = Key, {ok, SchemaBin} = file:read_file(File), {ok, #file_info{mtime = Mtime}} = file:read_file_info(File), - Schema = jsx:decode(SchemaBin, [{return_maps, false}]), + Schema = jesse_lib:json_decode(SchemaBin), SchemaInfos = [{Key, Mtime, Schema}], ValidationFun = fun jesse_lib:is_json_object/1, store_schemas(SchemaInfos, ValidationFun). @@ -321,7 +321,7 @@ add_http_uri(Key0) -> , HttpOptions , [{body_format, binary}]), {{_Line, 200, _}, Headers, SchemaBin} = Response, - Schema = jsx:decode(SchemaBin, [{return_maps, false}]), + Schema = jesse_lib:json_decode(SchemaBin), SchemaInfos = [{Key, get_http_mtime(Headers), Schema}], ValidationFun = fun jesse_lib:is_json_object/1, store_schemas(SchemaInfos, ValidationFun). diff --git a/src/jesse_error.erl b/src/jesse_error.erl index 32c12a8..c756b2a 100644 --- a/src/jesse_error.erl +++ b/src/jesse_error.erl @@ -27,7 +27,6 @@ , handle_data_invalid/3 , handle_schema_invalid/2 , to_json/1 - , to_json/2 , reason_to_jsx/1 ]). @@ -105,14 +104,9 @@ handle_schema_invalid(Info, State) -> %% @doc Convert an error to a JSON string using jsx -spec to_json(Error :: error()) -> binary(). -to_json(Error) -> - to_json(Error, [indent]). - -%% @doc Convert an error to a JSON string using jsx --spec to_json(Error :: error(), JsxOptions :: [atom()]) -> binary(). -to_json({error, Reasons}, JsxOptions) -> +to_json({error, Reasons}) -> JsxReasons = lists:map(fun reason_to_jsx/1, Reasons), - jsx:encode([{reasons, JsxReasons}], JsxOptions). + jesse_lib:json_encode([{reasons, JsxReasons}]). %% @doc Convert an error reason to jsx structs -spec reason_to_jsx(Reason :: error_reason()) -> jesse:json_term(). diff --git a/src/jesse_lib.erl b/src/jesse_lib.erl index 6535266..f6b9371 100644 --- a/src/jesse_lib.erl +++ b/src/jesse_lib.erl @@ -35,11 +35,36 @@ , get_schema_id_key/1 , get_schema_id/1 , get_schema_id/2 + , json_encode/1 + , json_decode/1 ]). %% Includes -include("jesse_schema_validator.hrl"). +%% Use new json library if available +-ifdef(OTP_RELEASE). + -if(?OTP_RELEASE >= 27). + %% OTP 27 or higher +json_decode(Bin) -> + json:decode(Bin). +json_encode(Bin) -> + json:encode(Bin). + -else. + %% OTP 26 to 21. +json_decode(Bin) -> + jsx:decode(Bin, [{return_maps, false}]). +json_encode(Bin) -> + jsx:encode(Bin). + -endif. +-else. + %% OTP 20 or lower. +json_decode(Bin) -> + jsx:decode(Bin, [{return_maps, false}]). +json_encode(Bin) -> + jsx:encode(Bin). +-endif. + %%% API %% @doc Returns an empty list if the given value is ?not_found. -spec empty_if_not_found(Value :: any()) -> any(). diff --git a/src/jesse_validator_draft4.erl b/src/jesse_validator_draft4.erl index cc6d074..98d25d5 100644 --- a/src/jesse_validator_draft4.erl +++ b/src/jesse_validator_draft4.erl @@ -1335,6 +1335,15 @@ remove_last_from_path(State) -> jesse_state:remove_last_from_path(State). %% @private +-ifdef(OTP_RELEASE). +%% OTP 21 or higher +valid_datetime(DateTimeBin) -> + try calendar:rfc3339_to_system_time(binary_to_list(DateTimeBin)) of + _ -> true + catch error:_Error -> false + end. +-else. +%% OTP 20 or lower. valid_datetime(DateTimeBin) -> case rfc3339:parse(DateTimeBin) of {ok, _} -> @@ -1342,6 +1351,7 @@ valid_datetime(DateTimeBin) -> _ -> false end. +-endif. maybe_external_check_value(Value, State) -> case jesse_state:get_external_validator(State) of diff --git a/src/jesse_validator_draft6.erl b/src/jesse_validator_draft6.erl index e43d161..a54103c 100644 --- a/src/jesse_validator_draft6.erl +++ b/src/jesse_validator_draft6.erl @@ -1285,6 +1285,15 @@ remove_last_from_path(State) -> jesse_state:remove_last_from_path(State). %% @private +-ifdef(OTP_RELEASE). +%% OTP 21 or higher +valid_datetime(DateTimeBin) -> + try calendar:rfc3339_to_system_time(binary_to_list(DateTimeBin)) of + _ -> true + catch error:_Error -> false + end. +-else. +%% OTP 20 or lower. valid_datetime(DateTimeBin) -> case rfc3339:parse(DateTimeBin) of {ok, _} -> @@ -1292,6 +1301,7 @@ valid_datetime(DateTimeBin) -> _ -> false end. +-endif. maybe_external_check_value(Value, State) -> case jesse_state:get_external_validator(State) of