Merge pull request #44 from ericbmerritt/master
additional features around command line output support and type conversions
This commit is contained in:
commit
82ec98667e
3 changed files with 588 additions and 0 deletions
24
include/ec_cmd_log.hrl
Normal file
24
include/ec_cmd_log.hrl
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
%% -*- erlang-indent-level: 4; indent-tabs-mode: nil; fill-column: 80 -*-
|
||||||
|
%%% Copyright 2012 Erlware, LLC. All Rights Reserved.
|
||||||
|
%%%
|
||||||
|
%%% This file is provided to you under the Apache License,
|
||||||
|
%%% Version 2.0 (the "License"); you may not use this file
|
||||||
|
%%% except in compliance with the License. You may obtain
|
||||||
|
%%% a copy of the License at
|
||||||
|
%%%
|
||||||
|
%%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%%
|
||||||
|
%%% Unless required by applicable law or agreed to in writing,
|
||||||
|
%%% software distributed under the License is distributed on an
|
||||||
|
%%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
%%% KIND, either express or implied. See the License for the
|
||||||
|
%%% specific language governing permissions and limitations
|
||||||
|
%%% under the License.
|
||||||
|
%%%---------------------------------------------------------------------------
|
||||||
|
%%% @author Eric Merritt <ericbmerritt@gmail.com>
|
||||||
|
%%% @copyright (C) 2012 Erlware, LLC.
|
||||||
|
|
||||||
|
-define(EC_ERROR, 0).
|
||||||
|
-define(EC_WARN, 1).
|
||||||
|
-define(EC_INFO, 2).
|
||||||
|
-define(EC_DEBUG, 3).
|
255
src/ec_cmd_log.erl
Normal file
255
src/ec_cmd_log.erl
Normal file
|
@ -0,0 +1,255 @@
|
||||||
|
%% -*- erlang-indent-level: 4; indent-tabs-mode: nil; fill-column: 80 -*-
|
||||||
|
%%% Copyright 2012 Erlware, LLC. All Rights Reserved.
|
||||||
|
%%%
|
||||||
|
%%% This file is provided to you under the Apache License,
|
||||||
|
%%% Version 2.0 (the "License"); you may not use this file
|
||||||
|
%%% except in compliance with the License. You may obtain
|
||||||
|
%%% a copy of the License at
|
||||||
|
%%%
|
||||||
|
%%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%%
|
||||||
|
%%% Unless required by applicable law or agreed to in writing,
|
||||||
|
%%% software distributed under the License is distributed on an
|
||||||
|
%%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
%%% KIND, either express or implied. See the License for the
|
||||||
|
%%% specific language governing permissions and limitations
|
||||||
|
%%% under the License.
|
||||||
|
%%%---------------------------------------------------------------------------
|
||||||
|
%%% @author Eric Merritt <ericbmerritt@gmail.com>
|
||||||
|
%%% @copyright (C) 2012 Erlware, LLC.
|
||||||
|
%%%
|
||||||
|
%%% @doc This provides simple output functions for command line apps. You should
|
||||||
|
%%% use this to talk to the users if you are wrting code for the system
|
||||||
|
-module(ec_cmd_log).
|
||||||
|
|
||||||
|
-export([new/1,
|
||||||
|
new/2,
|
||||||
|
log/4,
|
||||||
|
should/2,
|
||||||
|
debug/2,
|
||||||
|
debug/3,
|
||||||
|
info/2,
|
||||||
|
info/3,
|
||||||
|
error/2,
|
||||||
|
error/3,
|
||||||
|
warn/2,
|
||||||
|
warn/3,
|
||||||
|
log_level/1,
|
||||||
|
atom_log_level/1,
|
||||||
|
format/1]).
|
||||||
|
|
||||||
|
-include_lib("erlware_commons/include/ec_cmd_log.hrl").
|
||||||
|
|
||||||
|
-define(RED, 31).
|
||||||
|
-define(GREEN, 32).
|
||||||
|
-define(YELLOW, 33).
|
||||||
|
-define(BLUE, 34).
|
||||||
|
-define(MAGENTA, 35).
|
||||||
|
-define(CYAN, 36).
|
||||||
|
|
||||||
|
-define(PREFIX, "===> ").
|
||||||
|
|
||||||
|
-record(state_t, {mod=?MODULE :: ec_log,
|
||||||
|
log_level=0 :: int_log_level(),
|
||||||
|
caller=api :: api | command_line}).
|
||||||
|
|
||||||
|
%%============================================================================
|
||||||
|
%% types
|
||||||
|
%%============================================================================
|
||||||
|
-export_type([t/0,
|
||||||
|
int_log_level/0,
|
||||||
|
atom_log_level/0,
|
||||||
|
log_level/0,
|
||||||
|
log_fun/0]).
|
||||||
|
|
||||||
|
-type log_level() :: int_log_level() | atom_log_level().
|
||||||
|
|
||||||
|
-type int_log_level() :: 0..3.
|
||||||
|
|
||||||
|
-type atom_log_level() :: error | warn | info | debug.
|
||||||
|
|
||||||
|
-type log_fun() :: fun(() -> iolist()).
|
||||||
|
|
||||||
|
-type color() :: 31..36.
|
||||||
|
|
||||||
|
-opaque t() :: record(state_t).
|
||||||
|
|
||||||
|
%%============================================================================
|
||||||
|
%% API
|
||||||
|
%%============================================================================
|
||||||
|
%% @doc Create a new 'log level' for the system
|
||||||
|
-spec new(log_level()) -> t().
|
||||||
|
new(LogLevel) ->
|
||||||
|
new(LogLevel, api).
|
||||||
|
|
||||||
|
new(LogLevel, Caller) when LogLevel >= 0, LogLevel =< 3 ->
|
||||||
|
#state_t{mod=?MODULE, log_level=LogLevel, caller=Caller};
|
||||||
|
new(AtomLogLevel, Caller)
|
||||||
|
when AtomLogLevel =:= error;
|
||||||
|
AtomLogLevel =:= warn;
|
||||||
|
AtomLogLevel =:= info;
|
||||||
|
AtomLogLevel =:= debug ->
|
||||||
|
LogLevel = case AtomLogLevel of
|
||||||
|
error -> 0;
|
||||||
|
warn -> 1;
|
||||||
|
info -> 2;
|
||||||
|
debug -> 3
|
||||||
|
end,
|
||||||
|
new(LogLevel, Caller).
|
||||||
|
|
||||||
|
%% @doc log at the debug level given the current log state with a string or
|
||||||
|
%% function that returns a string
|
||||||
|
-spec debug(t(), string() | log_fun()) -> ok.
|
||||||
|
debug(LogState, Fun)
|
||||||
|
when erlang:is_function(Fun) ->
|
||||||
|
log(LogState, ?EC_DEBUG, fun() ->
|
||||||
|
colorize(LogState, ?CYAN, false, Fun())
|
||||||
|
end);
|
||||||
|
debug(LogState, String) ->
|
||||||
|
debug(LogState, "~s~n", [String]).
|
||||||
|
|
||||||
|
%% @doc log at the debug level given the current log state with a format string
|
||||||
|
%% and argements @see io:format/2
|
||||||
|
-spec debug(t(), string(), [any()]) -> ok.
|
||||||
|
debug(LogState, FormatString, Args) ->
|
||||||
|
log(LogState, ?EC_DEBUG, colorize(LogState, ?CYAN, false, FormatString), Args).
|
||||||
|
|
||||||
|
%% @doc log at the info level given the current log state with a string or
|
||||||
|
%% function that returns a string
|
||||||
|
-spec info(t(), string() | log_fun()) -> ok.
|
||||||
|
info(LogState, Fun)
|
||||||
|
when erlang:is_function(Fun) ->
|
||||||
|
log(LogState, ?EC_INFO, fun() ->
|
||||||
|
colorize(LogState, ?GREEN, false, Fun())
|
||||||
|
end);
|
||||||
|
info(LogState, String) ->
|
||||||
|
info(LogState, "~s~n", [String]).
|
||||||
|
|
||||||
|
%% @doc log at the info level given the current log state with a format string
|
||||||
|
%% and argements @see io:format/2
|
||||||
|
-spec info(t(), string(), [any()]) -> ok.
|
||||||
|
info(LogState, FormatString, Args) ->
|
||||||
|
log(LogState, ?EC_INFO, colorize(LogState, ?GREEN, false, FormatString), Args).
|
||||||
|
|
||||||
|
%% @doc log at the error level given the current log state with a string or
|
||||||
|
%% format string that returns a function
|
||||||
|
-spec error(t(), string() | log_fun()) -> ok.
|
||||||
|
error(LogState, Fun)
|
||||||
|
when erlang:is_function(Fun) ->
|
||||||
|
log(LogState, ?EC_ERROR, fun() ->
|
||||||
|
colorize(LogState, ?RED, false, Fun())
|
||||||
|
end);
|
||||||
|
error(LogState, String) ->
|
||||||
|
error(LogState, "~s~n", [String]).
|
||||||
|
|
||||||
|
%% @doc log at the error level given the current log state with a format string
|
||||||
|
%% and argements @see io:format/2
|
||||||
|
-spec error(t(), string(), [any()]) -> ok.
|
||||||
|
error(LogState, FormatString, Args) ->
|
||||||
|
log(LogState, ?EC_ERROR, colorize(LogState, ?GREEN, false, FormatString), Args).
|
||||||
|
|
||||||
|
%% @doc log at the warn level given the current log state with a string or
|
||||||
|
%% format string that returns a function
|
||||||
|
-spec warn(t(), string() | log_fun()) -> ok.
|
||||||
|
warn(LogState, Fun)
|
||||||
|
when erlang:is_function(Fun) ->
|
||||||
|
log(LogState, ?EC_WARN, fun() -> colorize(LogState, ?MAGENTA, false, Fun()) end);
|
||||||
|
warn(LogState, String) ->
|
||||||
|
warn(LogState, "~s~n", [String]).
|
||||||
|
|
||||||
|
%% @doc log at the warn level given the current log state with a format string
|
||||||
|
%% and argements @see io:format/2
|
||||||
|
-spec warn(t(), string(), [any()]) -> ok.
|
||||||
|
warn(LogState, FormatString, Args) ->
|
||||||
|
log(LogState, ?EC_WARN, colorize(LogState, ?MAGENTA, false, FormatString), Args).
|
||||||
|
|
||||||
|
%% @doc Execute the fun passed in if log level is as expected.
|
||||||
|
-spec log(t(), int_log_level(), log_fun()) -> ok.
|
||||||
|
log(#state_t{mod=?MODULE, log_level=DetailLogLevel}, LogLevel, Fun)
|
||||||
|
when DetailLogLevel >= LogLevel ->
|
||||||
|
io:format("~s~n", [Fun()]);
|
||||||
|
log(_, _, _) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
%% @doc when the module log level is less then or equal to the log level for the
|
||||||
|
%% call then write the log info out. When its not then ignore the call.
|
||||||
|
-spec log(t(), int_log_level(), string(), [any()]) -> ok.
|
||||||
|
log(#state_t{mod=?MODULE, log_level=DetailLogLevel}, LogLevel, FormatString, Args)
|
||||||
|
when DetailLogLevel >= LogLevel,
|
||||||
|
erlang:is_list(Args) ->
|
||||||
|
io:format(FormatString, Args);
|
||||||
|
log(_, _, _, _) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
%% @doc return a boolean indicating if the system should log for the specified
|
||||||
|
%% levelg
|
||||||
|
-spec should(t(), int_log_level() | any()) -> boolean().
|
||||||
|
should(#state_t{mod=?MODULE, log_level=DetailLogLevel}, LogLevel)
|
||||||
|
when DetailLogLevel >= LogLevel ->
|
||||||
|
true;
|
||||||
|
should(_, _) ->
|
||||||
|
false.
|
||||||
|
|
||||||
|
%% @doc get the current log level as an integer
|
||||||
|
-spec log_level(t()) -> int_log_level().
|
||||||
|
log_level(#state_t{mod=?MODULE, log_level=DetailLogLevel}) ->
|
||||||
|
DetailLogLevel.
|
||||||
|
|
||||||
|
%% @doc get the current log level as an atom
|
||||||
|
-spec atom_log_level(t()) -> atom_log_level().
|
||||||
|
atom_log_level(#state_t{mod=?MODULE, log_level=?EC_ERROR}) ->
|
||||||
|
error;
|
||||||
|
atom_log_level(#state_t{mod=?MODULE, log_level=?EC_WARN}) ->
|
||||||
|
warn;
|
||||||
|
atom_log_level(#state_t{mod=?MODULE, log_level=?EC_INFO}) ->
|
||||||
|
info;
|
||||||
|
atom_log_level(#state_t{mod=?MODULE, log_level=?EC_DEBUG}) ->
|
||||||
|
debug.
|
||||||
|
|
||||||
|
-spec format(t()) -> iolist().
|
||||||
|
format(Log) ->
|
||||||
|
[<<"(">>,
|
||||||
|
ec_cnv:to_binary(log_level(Log)), <<":">>,
|
||||||
|
ec_cnv:to_binary(atom_log_level(Log)),
|
||||||
|
<<")">>].
|
||||||
|
|
||||||
|
-spec colorize(t(), color(), boolean(), string()) -> string().
|
||||||
|
colorize(#state_t{caller=command_line}, Color, false, Msg) when is_integer(Color) ->
|
||||||
|
colorize_(Color, 0, Msg);
|
||||||
|
colorize(_LogState, _Color, _Bold, Msg) ->
|
||||||
|
Msg.
|
||||||
|
|
||||||
|
-spec colorize_(color(), integer(), string()) -> string().
|
||||||
|
colorize_(Color, Bold, Msg) when is_integer(Color), is_integer(Bold)->
|
||||||
|
lists:flatten(io_lib:format("\033[~B;~Bm~s~s\033[0m", [Bold, Color, ?PREFIX, Msg])).
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Test Functions
|
||||||
|
%%%===================================================================
|
||||||
|
|
||||||
|
-ifndef(NOTEST).
|
||||||
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
should_test() ->
|
||||||
|
ErrorLogState = new(error),
|
||||||
|
?assertMatch(true, should(ErrorLogState, ?EC_ERROR)),
|
||||||
|
?assertMatch(true, not should(ErrorLogState, ?EC_INFO)),
|
||||||
|
?assertMatch(true, not should(ErrorLogState, ?EC_DEBUG)),
|
||||||
|
?assertEqual(?EC_ERROR, log_level(ErrorLogState)),
|
||||||
|
?assertEqual(error, atom_log_level(ErrorLogState)),
|
||||||
|
|
||||||
|
InfoLogState = new(info),
|
||||||
|
?assertMatch(true, should(InfoLogState, ?EC_ERROR)),
|
||||||
|
?assertMatch(true, should(InfoLogState, ?EC_INFO)),
|
||||||
|
?assertMatch(true, not should(InfoLogState, ?EC_DEBUG)),
|
||||||
|
?assertEqual(?EC_INFO, log_level(InfoLogState)),
|
||||||
|
?assertEqual(info, atom_log_level(InfoLogState)),
|
||||||
|
|
||||||
|
DebugLogState = new(debug),
|
||||||
|
?assertMatch(true, should(DebugLogState, ?EC_ERROR)),
|
||||||
|
?assertMatch(true, should(DebugLogState, ?EC_INFO)),
|
||||||
|
?assertMatch(true, should(DebugLogState, ?EC_DEBUG)),
|
||||||
|
?assertEqual(?EC_DEBUG, log_level(DebugLogState)),
|
||||||
|
?assertEqual(debug, atom_log_level(DebugLogState)).
|
||||||
|
|
||||||
|
-endif.
|
309
src/ec_cnv.erl
Normal file
309
src/ec_cnv.erl
Normal file
|
@ -0,0 +1,309 @@
|
||||||
|
%% -*- erlang-indent-level: 4; indent-tabs-mode: nil; fill-column: 80 -*-
|
||||||
|
%%% Copyright 2012 Erlware, LLC. All Rights Reserved.
|
||||||
|
%%%
|
||||||
|
%%% This file is provided to you under the Apache License,
|
||||||
|
%%% Version 2.0 (the "License"); you may not use this file
|
||||||
|
%%% except in compliance with the License. You may obtain
|
||||||
|
%%% a copy of the License at
|
||||||
|
%%%
|
||||||
|
%%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%%
|
||||||
|
%%% Unless required by applicable law or agreed to in writing,
|
||||||
|
%%% software distributed under the License is distributed on an
|
||||||
|
%%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
%%% KIND, either express or implied. See the License for the
|
||||||
|
%%% specific language governing permissions and limitations
|
||||||
|
%%% under the License.
|
||||||
|
%%%---------------------------------------------------------------------------
|
||||||
|
%%% @author Eric Merritt <ericbmerritt@gmail.com>
|
||||||
|
%%% @copyright (C) 2012 Erlware, LLC.
|
||||||
|
%%%
|
||||||
|
-module(ec_cnv).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([to_integer/1,
|
||||||
|
to_integer/2,
|
||||||
|
to_float/1,
|
||||||
|
to_float/2,
|
||||||
|
to_number/1,
|
||||||
|
to_list/1,
|
||||||
|
to_binary/1,
|
||||||
|
to_atom/1,
|
||||||
|
to_boolean/1,
|
||||||
|
is_true/1,
|
||||||
|
is_false/1]).
|
||||||
|
|
||||||
|
-ifndef(NOTEST).
|
||||||
|
-include_lib("proper/include/proper.hrl").
|
||||||
|
-endif.
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% API
|
||||||
|
%%%===================================================================
|
||||||
|
|
||||||
|
%% @doc
|
||||||
|
%% Automatic conversion of a term into integer type. The conversion
|
||||||
|
%% will round a float value if nonstrict is specified otherwise badarg
|
||||||
|
-spec to_integer(string() | binary() | integer() | float()) ->
|
||||||
|
integer().
|
||||||
|
to_integer(X)->
|
||||||
|
to_integer(X, nonstrict).
|
||||||
|
|
||||||
|
-spec to_integer(string() | binary() | integer() | float(),
|
||||||
|
strict | nonstrict) ->
|
||||||
|
integer().
|
||||||
|
to_integer(X, strict)
|
||||||
|
when erlang:is_float(X) ->
|
||||||
|
erlang:error(badarg);
|
||||||
|
to_integer(X, nonstrict)
|
||||||
|
when erlang:is_float(X) ->
|
||||||
|
erlang:round(X);
|
||||||
|
to_integer(X, S)
|
||||||
|
when erlang:is_binary(X) ->
|
||||||
|
to_integer(erlang:binary_to_list(X), S);
|
||||||
|
to_integer(X, S)
|
||||||
|
when erlang:is_list(X) ->
|
||||||
|
try erlang:list_to_integer(X) of
|
||||||
|
Result ->
|
||||||
|
Result
|
||||||
|
catch
|
||||||
|
error:badarg when S =:= nonstrict ->
|
||||||
|
erlang:round(erlang:list_to_float(X))
|
||||||
|
end;
|
||||||
|
to_integer(X, _)
|
||||||
|
when erlang:is_integer(X) ->
|
||||||
|
X.
|
||||||
|
|
||||||
|
%% @doc
|
||||||
|
%% Automatic conversion of a term into float type. badarg if strict
|
||||||
|
%% is defined and an integer value is passed.
|
||||||
|
-spec to_float(string() | binary() | integer() | float()) ->
|
||||||
|
float().
|
||||||
|
to_float(X) ->
|
||||||
|
to_float(X, nonstrict).
|
||||||
|
|
||||||
|
-spec to_float(string() | binary() | integer() | float(),
|
||||||
|
strict | nonstrict) ->
|
||||||
|
float().
|
||||||
|
to_float(X, S) when is_binary(X) ->
|
||||||
|
to_float(erlang:binary_to_list(X), S);
|
||||||
|
to_float(X, S)
|
||||||
|
when erlang:is_list(X) ->
|
||||||
|
try erlang:list_to_float(X) of
|
||||||
|
Result ->
|
||||||
|
Result
|
||||||
|
catch
|
||||||
|
error:badarg when S =:= nonstrict ->
|
||||||
|
erlang:list_to_integer(X) * 1.0
|
||||||
|
end;
|
||||||
|
to_float(X, strict) when
|
||||||
|
erlang:is_integer(X) ->
|
||||||
|
erlang:error(badarg);
|
||||||
|
to_float(X, nonstrict)
|
||||||
|
when erlang:is_integer(X) ->
|
||||||
|
X * 1.0;
|
||||||
|
to_float(X, _) when erlang:is_float(X) ->
|
||||||
|
X.
|
||||||
|
|
||||||
|
%% @doc
|
||||||
|
%% Automatic conversion of a term into number type.
|
||||||
|
-spec to_number(binary() | string() | number()) ->
|
||||||
|
number().
|
||||||
|
to_number(X)
|
||||||
|
when erlang:is_number(X) ->
|
||||||
|
X;
|
||||||
|
to_number(X)
|
||||||
|
when erlang:is_binary(X) ->
|
||||||
|
to_number(to_list(X));
|
||||||
|
to_number(X)
|
||||||
|
when erlang:is_list(X) ->
|
||||||
|
try list_to_integer(X) of
|
||||||
|
Int -> Int
|
||||||
|
catch
|
||||||
|
error:badarg ->
|
||||||
|
list_to_float(X)
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% @doc
|
||||||
|
%% Automatic conversion of a term into Erlang list
|
||||||
|
-spec to_list(atom() | list() | binary() | integer() | float()) ->
|
||||||
|
list().
|
||||||
|
to_list(X)
|
||||||
|
when erlang:is_float(X) ->
|
||||||
|
erlang:float_to_list(X);
|
||||||
|
to_list(X)
|
||||||
|
when erlang:is_integer(X) ->
|
||||||
|
erlang:integer_to_list(X);
|
||||||
|
to_list(X)
|
||||||
|
when erlang:is_binary(X) ->
|
||||||
|
erlang:binary_to_list(X);
|
||||||
|
to_list(X)
|
||||||
|
when erlang:is_atom(X) ->
|
||||||
|
erlang:atom_to_list(X);
|
||||||
|
to_list(X)
|
||||||
|
when erlang:is_list(X) ->
|
||||||
|
X.
|
||||||
|
|
||||||
|
%% @doc
|
||||||
|
%% Known limitations:
|
||||||
|
%% Converting [256 | _], lists with integers > 255
|
||||||
|
-spec to_binary(atom() | string() | binary() | integer() | float()) ->
|
||||||
|
binary().
|
||||||
|
to_binary(X)
|
||||||
|
when erlang:is_float(X) ->
|
||||||
|
to_binary(to_list(X));
|
||||||
|
to_binary(X)
|
||||||
|
when erlang:is_integer(X) ->
|
||||||
|
erlang:iolist_to_binary(integer_to_list(X));
|
||||||
|
to_binary(X)
|
||||||
|
when erlang:is_atom(X) ->
|
||||||
|
erlang:list_to_binary(erlang:atom_to_list(X));
|
||||||
|
to_binary(X)
|
||||||
|
when erlang:is_list(X) ->
|
||||||
|
erlang:iolist_to_binary(X);
|
||||||
|
to_binary(X)
|
||||||
|
when erlang:is_binary(X) ->
|
||||||
|
X.
|
||||||
|
|
||||||
|
-spec to_boolean(binary() | string() | atom()) ->
|
||||||
|
boolean().
|
||||||
|
to_boolean(<<"true">>) ->
|
||||||
|
true;
|
||||||
|
to_boolean("true") ->
|
||||||
|
true;
|
||||||
|
to_boolean(true) ->
|
||||||
|
true;
|
||||||
|
to_boolean(<<"false">>) ->
|
||||||
|
false;
|
||||||
|
to_boolean("false") ->
|
||||||
|
false;
|
||||||
|
to_boolean(false) ->
|
||||||
|
false.
|
||||||
|
|
||||||
|
-spec is_true(binary() | string() | atom()) ->
|
||||||
|
boolean().
|
||||||
|
is_true(<<"true">>) ->
|
||||||
|
true;
|
||||||
|
is_true("true") ->
|
||||||
|
true;
|
||||||
|
is_true(true) ->
|
||||||
|
true;
|
||||||
|
is_true(_) ->
|
||||||
|
false.
|
||||||
|
|
||||||
|
-spec is_false(binary() | string() | atom()) ->
|
||||||
|
boolean().
|
||||||
|
is_false(<<"false">>) ->
|
||||||
|
true;
|
||||||
|
is_false("false") ->
|
||||||
|
true;
|
||||||
|
is_false(false) ->
|
||||||
|
true;
|
||||||
|
is_false(_) ->
|
||||||
|
false.
|
||||||
|
|
||||||
|
%% @doc
|
||||||
|
%% Automation conversion a term to an existing atom. badarg is
|
||||||
|
%% returned if the atom doesn't exist. the safer version, won't let
|
||||||
|
%% you leak atoms
|
||||||
|
-spec to_atom(atom() | list() | binary() | integer() | float()) ->
|
||||||
|
atom().
|
||||||
|
to_atom(X)
|
||||||
|
when erlang:is_atom(X) ->
|
||||||
|
X;
|
||||||
|
to_atom(X)
|
||||||
|
when erlang:is_list(X) ->
|
||||||
|
erlang:list_to_existing_atom(X);
|
||||||
|
to_atom(X) ->
|
||||||
|
to_atom(to_list(X)).
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% API
|
||||||
|
%%%===================================================================
|
||||||
|
|
||||||
|
-ifndef(NOTEST).
|
||||||
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
force_proper_test_() ->
|
||||||
|
{"Runs PropEr test during EUnit phase",
|
||||||
|
{timeout, 15000, [?_assertEqual([], proper:module(?MODULE))]}}.
|
||||||
|
|
||||||
|
to_integer_test() ->
|
||||||
|
?assertError(badarg, to_integer(1.5, strict)).
|
||||||
|
|
||||||
|
to_float_test() ->
|
||||||
|
?assertError(badarg, to_float(10, strict)).
|
||||||
|
|
||||||
|
to_atom_test() ->
|
||||||
|
?assertMatch(true, to_atom("true")),
|
||||||
|
?assertMatch(true, to_atom(<<"true">>)),
|
||||||
|
?assertMatch(false, to_atom(<<"false">>)),
|
||||||
|
?assertMatch(false, to_atom(false)),
|
||||||
|
?assertError(badarg, to_atom("hello_foo_bar_baz")),
|
||||||
|
|
||||||
|
S = erlang:list_to_atom("1"),
|
||||||
|
?assertMatch(S, to_atom(1)).
|
||||||
|
|
||||||
|
to_boolean_test()->
|
||||||
|
?assertMatch(true, to_boolean(<<"true">>)),
|
||||||
|
?assertMatch(true, to_boolean("true")),
|
||||||
|
?assertMatch(true, to_boolean(true)),
|
||||||
|
?assertMatch(false, to_boolean(<<"false">>)),
|
||||||
|
?assertMatch(false, to_boolean("false")),
|
||||||
|
?assertMatch(false, to_boolean(false)).
|
||||||
|
|
||||||
|
%%% PropEr testing
|
||||||
|
|
||||||
|
prop_to_integer() ->
|
||||||
|
?FORALL({F, I}, {float(), integer()},
|
||||||
|
begin
|
||||||
|
Is = [[Fun(N), N] ||
|
||||||
|
Fun <- [fun to_list/1,
|
||||||
|
fun to_binary/1],
|
||||||
|
N <- [F, I]],
|
||||||
|
lists:all(fun([FN, N]) ->
|
||||||
|
erlang:is_integer(to_integer(N)) andalso
|
||||||
|
erlang:is_integer(to_integer(FN))
|
||||||
|
end, Is)
|
||||||
|
end).
|
||||||
|
|
||||||
|
prop_to_list() ->
|
||||||
|
?FORALL({A, L, B, I, F}, {atom(), list(), binary(), integer(), float()},
|
||||||
|
lists:all(fun(X) ->
|
||||||
|
erlang:is_list(to_list(X))
|
||||||
|
end, [A, L, B, I, F])).
|
||||||
|
|
||||||
|
prop_to_binary() ->
|
||||||
|
?FORALL({A, L, B, I, F, IO}, {atom(), list(range(0,255)), binary(),
|
||||||
|
integer(), float(), iolist()},
|
||||||
|
lists:all(fun(X) ->
|
||||||
|
erlang:is_binary(to_binary(X))
|
||||||
|
end, [A, L, B, I, F, IO])).
|
||||||
|
|
||||||
|
prop_iolist_t() ->
|
||||||
|
?FORALL(IO, iolist(), erlang:is_binary(to_binary(IO))).
|
||||||
|
|
||||||
|
prop_to_float() ->
|
||||||
|
?FORALL({F, I}, {float(), integer()},
|
||||||
|
begin
|
||||||
|
Fs = [[Fun(N), N] ||
|
||||||
|
Fun <- [fun to_list/1, fun to_binary/1],
|
||||||
|
N <- [F, I]],
|
||||||
|
lists:all(fun([FN, N]) ->
|
||||||
|
erlang:is_float(to_float(N)) andalso
|
||||||
|
erlang:is_float(to_float(FN))
|
||||||
|
end, Fs)
|
||||||
|
end).
|
||||||
|
|
||||||
|
prop_to_number() ->
|
||||||
|
?FORALL({F, I}, {float(), integer()},
|
||||||
|
begin
|
||||||
|
Is = [[Fun(N), N] ||
|
||||||
|
Fun <- [fun to_list/1, fun to_binary/1],
|
||||||
|
N <- [F, I] ],
|
||||||
|
lists:all(fun([FN, N]) ->
|
||||||
|
erlang:is_number(to_number(N)) andalso
|
||||||
|
erlang:is_number(to_number(FN))
|
||||||
|
end, Is)
|
||||||
|
end).
|
||||||
|
-endif.
|
Loading…
Add table
Add a link
Reference in a new issue