formatters #14
@ -4,22 +4,22 @@
|
||||
|
||||
-module(hz_format).
|
||||
|
||||
-export([price/1, price/2, price/3, price/4,
|
||||
% read/1, read/2,
|
||||
-export([amount/1, amount/2, amount/3, amount/4,
|
||||
read/1,
|
||||
price_to_string/1, string_to_price/1]).
|
||||
|
||||
-spec price(Pucks) -> Formatted
|
||||
-spec amount(Pucks) -> Formatted
|
||||
when Pucks :: integer(),
|
||||
Formatted :: string().
|
||||
%% @doc
|
||||
%% A convenience formatting function.
|
||||
%% @equiv price(us, Pucks).
|
||||
%% @equiv amount(us, Pucks).
|
||||
|
||||
price(Pucks) ->
|
||||
price(us, Pucks).
|
||||
amount(Pucks) ->
|
||||
amount(us, Pucks).
|
||||
|
||||
|
||||
-spec price(Style, Pucks) -> Formatted
|
||||
-spec amount(Style, Pucks) -> Formatted
|
||||
when Style :: us | jp | metric | heresy | {Separator, Span},
|
||||
Separator :: $, | $_,
|
||||
Span :: 3 | 4,
|
||||
@ -27,13 +27,13 @@ price(Pucks) ->
|
||||
Formatted :: string().
|
||||
%% @doc
|
||||
%% A money formatting function.
|
||||
%% @equiv price(gaju, Style, Pucks).
|
||||
%% @equiv amount(gaju, Style, Pucks).
|
||||
|
||||
price(Style, Pucks) ->
|
||||
price(gaju, Style, Pucks).
|
||||
amount(Style, Pucks) ->
|
||||
amount(gaju, Style, Pucks).
|
||||
|
||||
|
||||
-spec price(Unit, Style, Pucks) -> Formatted
|
||||
-spec amount(Unit, Style, Pucks) -> Formatted
|
||||
when Unit :: gaju | puck,
|
||||
Style :: us | jp | metric | heresy | {Separator, Span},
|
||||
Separator :: $, | $_,
|
||||
@ -43,23 +43,23 @@ price(Style, Pucks) ->
|
||||
%% @doc
|
||||
%% A simplified format function covering the most common formats desired.
|
||||
|
||||
price(gaju, us, Pucks) ->
|
||||
amount(gaju, us, Pucks) ->
|
||||
western($,, $., 3, all, Pucks);
|
||||
price(puck, us, Pucks) ->
|
||||
amount(puck, us, Pucks) ->
|
||||
western($,, 3, Pucks);
|
||||
price(Unit, jp, Pucks) ->
|
||||
amount(Unit, jp, Pucks) ->
|
||||
jp(Unit, all, Pucks);
|
||||
price(Unit, metric, Pucks) ->
|
||||
amount(Unit, metric, Pucks) ->
|
||||
bestern(Unit, ranks(metric), all, Pucks);
|
||||
price(Unit, heresy, Pucks) ->
|
||||
amount(Unit, heresy, Pucks) ->
|
||||
bestern(Unit, ranks(heresy), all, Pucks);
|
||||
price(gaju, {Separator, Span}, Pucks) ->
|
||||
amount(gaju, {Separator, Span}, Pucks) ->
|
||||
western(Separator, $., Span, all, Pucks);
|
||||
price(puck, {Separator, Span}, Pucks) ->
|
||||
amount(puck, {Separator, Span}, Pucks) ->
|
||||
western(Separator, Span, Pucks).
|
||||
|
||||
|
||||
-spec price(Unit, Style, Precision, Pucks) -> Serialized
|
||||
-spec amount(Unit, Style, Precision, Pucks) -> Serialized
|
||||
when Unit :: gaju | puck,
|
||||
Style :: us | jp | metric | heresy | {Separator, Span},
|
||||
Precision :: all | 0..18,
|
||||
@ -71,53 +71,53 @@ price(puck, {Separator, Span}, Pucks) ->
|
||||
%% A flexible, if annoyingly complex, formatting function.
|
||||
%%
|
||||
%% ```
|
||||
%% price(gaju, us, 3, 123456789123456789123456789) ->
|
||||
%% amount(gaju, us, 3, 123456789123456789123456789) ->
|
||||
%% "木123,456,789.123...".
|
||||
%%
|
||||
%% price(gaju, us, 3, 123456789123000000000000000) ->
|
||||
%% amount(gaju, us, 3, 123456789123000000000000000) ->
|
||||
%% "木123,456,789.123".
|
||||
%%
|
||||
%% price(gaju, {$,, 3}, 3, 123456789123456789123456789) ->
|
||||
%% amount(gaju, {$,, 3}, 3, 123456789123456789123456789) ->
|
||||
%% "木123,456,789.123...".
|
||||
%%
|
||||
%% price(gaju, {$,, 3}, 6, 123456789123000000000000000) ->
|
||||
%% amount(gaju, {$,, 3}, 6, 123456789123000000000000000) ->
|
||||
%% "木123,456,789.123"
|
||||
%%
|
||||
%% price(gaju, {$_, 4}, 10, 123456789123456789123456789) ->
|
||||
%% amount(gaju, {$_, 4}, 10, 123456789123456789123456789) ->
|
||||
%% "木1_2345_6789.1234_5678_91..."
|
||||
%%
|
||||
%% price(gaju, jp, 3, 123456789123456789123456789) ->
|
||||
%% amount(gaju, jp, 3, 123456789123456789123456789) ->
|
||||
%% "1億2345万6789木 12京3000兆本"
|
||||
%%
|
||||
%% price(gaju, jp, 6, 123456789123456789123456789) ->
|
||||
%% amount(gaju, jp, 6, 123456789123456789123456789) ->
|
||||
%% "1億2345万6789木 12京3456兆本"
|
||||
%%
|
||||
%% price(gaju, jp, 0, 123456789123456789123456789) ->
|
||||
%% amount(gaju, jp, 0, 123456789123456789123456789) ->
|
||||
%% "1億2345万6789木"
|
||||
%%
|
||||
%% price(puck, jp, all, 123456789123456789123456789) ->
|
||||
%% amount(puck, jp, all, 123456789123456789123456789) ->
|
||||
%% "123秭4567垓8912京3456兆7891億2345万6789本"
|
||||
%% '''
|
||||
|
||||
price(gaju, us, Precision, Pucks) ->
|
||||
amount(gaju, us, Precision, Pucks) ->
|
||||
western($,, $., 3, Precision, Pucks);
|
||||
price(gaju, jp, Precision, Pucks) ->
|
||||
amount(gaju, jp, Precision, Pucks) ->
|
||||
jp(gaju, Precision, Pucks);
|
||||
price(gaju, metric, Precision, Pucks) ->
|
||||
amount(gaju, metric, Precision, Pucks) ->
|
||||
bestern(gaju, ranks(metric), Precision, Pucks);
|
||||
price(gaju, legacy, Precision, Pucks) ->
|
||||
amount(gaju, legacy, Precision, Pucks) ->
|
||||
bestern(gaju, ranks(heresy), Precision, Pucks);
|
||||
price(gaju, {Separator, Span}, Precision, Pucks) ->
|
||||
amount(gaju, {Separator, Span}, Precision, Pucks) ->
|
||||
western(Separator, $., Span, Precision, Pucks);
|
||||
price(puck, us, _, Pucks) ->
|
||||
amount(puck, us, _, Pucks) ->
|
||||
western($,, 3, Pucks);
|
||||
price(puck, jp, _, Pucks) ->
|
||||
amount(puck, jp, _, Pucks) ->
|
||||
jp(puck, all, Pucks);
|
||||
price(puck, metric, _, Pucks) ->
|
||||
amount(puck, metric, _, Pucks) ->
|
||||
bestern(puck, ranks(metric), all, Pucks);
|
||||
price(puck, legacy, _, Pucks) ->
|
||||
amount(puck, legacy, _, Pucks) ->
|
||||
bestern(puck, ranks(heresy), all, Pucks);
|
||||
price(puck, {Separator, Span}, _, Pucks) ->
|
||||
amount(puck, {Separator, Span}, _, Pucks) ->
|
||||
western(Separator, Span, Pucks).
|
||||
|
||||
|
||||
@ -165,7 +165,6 @@ western2(Separator, Break, Span, Precision, Pucks) ->
|
||||
end.
|
||||
|
||||
decimal_pucks(all, PChars) ->
|
||||
io:format("decimal_pucks: PChars: ~p~n", [PChars]),
|
||||
RTrailing = lists:reverse(PChars),
|
||||
{lists:reverse(lists:dropwhile(fun(C) -> C =:= $0 end, RTrailing)), ""};
|
||||
decimal_pucks(Precision, PChars) ->
|
||||
@ -401,121 +400,85 @@ puck_mark() -> $本.
|
||||
one_gaju() -> 1_000_000_000_000_000_000.
|
||||
|
||||
|
||||
%-spec read(Format) -> Result
|
||||
% when Format :: string(),
|
||||
% Result :: {ok, Pucks} | {error, Reason},
|
||||
% Pucks :: integer(),
|
||||
% Reason :: {badarg, Partial :: string(), Rest :: term()}
|
||||
% | {incomplete, Partial :: string(), Rest :: binary()}
|
||||
% | format.
|
||||
%%% @doc
|
||||
%%% Convery any valid string formatted representation and output a value in pucks.
|
||||
%%% This routine can fail in the special case of `ch' style formatting with a single
|
||||
%%% comma and/or a single period in it, as this can trigger misinterpretation as `us'
|
||||
%%% style. When in doubt, always call `read/2' with a style specified.
|
||||
%
|
||||
%read(Format) ->
|
||||
% case assess_style(string:trim(Format)) of
|
||||
% us -> read(us, Format);
|
||||
% ch -> read(ch, Format);
|
||||
% jp -> read(jp, Format);
|
||||
% Error -> Error
|
||||
% end.
|
||||
%
|
||||
%assess_style([H1, H2 | Numbers])
|
||||
% when H1 =:= $木 orelse H1 =:= $本 orelse H2 =:= $木 orelse H2 =:= $本 ->
|
||||
% case count($., Numbers) > 1 of
|
||||
% false -> us;
|
||||
% true -> ch
|
||||
% end;
|
||||
%assess_style(Format) ->
|
||||
% case lists:member($木, Format) orelse lists:member($本, Format) of
|
||||
% true -> jp;
|
||||
% false -> {error, format}
|
||||
% end.
|
||||
%
|
||||
%count(Char, String) -> count(Char, String, 0).
|
||||
%
|
||||
%count(C, [C | T], A) -> count(C, T, A + 1);
|
||||
%count(C, [_ | T], A) -> count(C, T, A);
|
||||
%count(_, [], A) -> A.
|
||||
%
|
||||
%
|
||||
%-spec read(Style, Format) -> Result
|
||||
% when Style :: us | jp | metric | legacy | undefined,
|
||||
% Format :: string(),
|
||||
% Result :: {ok, Pucks} | {error, Reason},
|
||||
% Pucks :: integer(),
|
||||
% Reason :: {badarg, Partial :: string(), Rest :: term()}
|
||||
% | {incomplete, Partial :: string(), Rest :: binary()}
|
||||
% | format.
|
||||
%%% @doc
|
||||
%%% Convert any valid string formatted representation and output a value in pucks.
|
||||
%%% Note that this function is deliberately a bit too permissive in the case of
|
||||
%%% western formatting, stripping all non-halfwidth digit characters on the high
|
||||
%%% and low sides of the format once the break (decimal) character is identified
|
||||
%%% and sign is determined. That is to say, there are many ways to feed this wacky
|
||||
%%% strings and get a number out of it, so be aware.
|
||||
%
|
||||
%read(Style, Format) ->
|
||||
% case unicode:characters_to_list(Format) of
|
||||
% String when is_list(String) ->
|
||||
% Trimmed = string:trim(String),
|
||||
% read2(Style, Trimmed);
|
||||
% {error, Partial, Rest} ->
|
||||
% {error, {badarg, Partial, Rest}};
|
||||
% Incomplete ->
|
||||
% {error, Incomplete}
|
||||
% end.
|
||||
%
|
||||
%read2(us, Format) ->
|
||||
% read_western($., Format);
|
||||
%read2(jp, Format) ->
|
||||
% read_jp(Format);
|
||||
%read2(undefined, Format) ->
|
||||
% read(Format).
|
||||
%
|
||||
%read_western(Break, [$-, Format]) ->
|
||||
% case read_western2(Break, Format) of
|
||||
% {ok, Pucks} -> {ok, Pucks * -1};
|
||||
% Error -> Error
|
||||
% end;
|
||||
%read_western(Break, Format) ->
|
||||
% read_western2(Break, Format).
|
||||
%
|
||||
%read_western2(Break, Format) ->
|
||||
% case string:split(Format, [Break], all) of
|
||||
% [[], L] -> read_western3(0, L);
|
||||
% [H, []] -> read_western3(H, 0);
|
||||
% [H, L] -> read_western3(H, L);
|
||||
% [H] -> read_western3(H, 0);
|
||||
% _ -> {error, format}
|
||||
% end.
|
||||
%
|
||||
%read_western3(0, L) ->
|
||||
% read_l(L);
|
||||
%read_western3(H, 0) ->
|
||||
% case read_h(H) of
|
||||
% {ok, Gajus} -> {ok, Gajus * one_gaju()};
|
||||
% Error -> Error
|
||||
% end;
|
||||
%read_western3(H, L) ->
|
||||
% Gajus = read_h(H),
|
||||
% Pucks = read_l(L),
|
||||
% {ok, (Gajus * one_gaju()) + Pucks}.
|
||||
%
|
||||
%read_h(S) ->
|
||||
% case lists:filter(fun is_numchar/1, S) of
|
||||
% [] -> 0;
|
||||
% F -> list_to_integer(Filtered)
|
||||
% end.
|
||||
%
|
||||
%read_l(L) ->
|
||||
% case lists:filter(fun is_numchar/1, S) of
|
||||
% [] -> 0;
|
||||
% F -> list_to_integer(lists:flatten(string:pad(F, 18, trailing, $0)))
|
||||
% end.
|
||||
%
|
||||
-spec read(Format) -> Result
|
||||
when Format :: string(),
|
||||
Result :: {ok, Pucks} | {error, Reason},
|
||||
Pucks :: integer(),
|
||||
Reason :: {badarg, Partial :: string(), Rest :: term()}
|
||||
| {incomplete, Partial :: string(), Rest :: binary()}
|
||||
| format.
|
||||
%% @doc
|
||||
%% Convery any valid string formatted representation and output a value in pucks.
|
||||
%% This routine can fail in the special case of `ch' style formatting with a single
|
||||
%% comma and/or a single period in it, as this can trigger misinterpretation as `us'
|
||||
%% style. When in doubt, always call `read/2' with a style specified.
|
||||
|
||||
read([$木 | Rest]) ->
|
||||
read_w_gajus(Rest, []);
|
||||
read([$本 | Rest]) ->
|
||||
read_w_pucks(Rest, []);
|
||||
read([C | Rest])
|
||||
when C =:= $- orelse
|
||||
C =:= $− orelse
|
||||
C =:= $- ->
|
||||
case read(Rest) of
|
||||
{ok, Pucks} -> {ok, Pucks * -1};
|
||||
Error -> Error
|
||||
end;
|
||||
read([C | Rest])
|
||||
when C =:= 32 orelse % ASCII space
|
||||
C =:= 12288 orelse % full-width space
|
||||
C =:= $\t orelse
|
||||
C =:= $\r orelse
|
||||
C =:= $\n ->
|
||||
read(Rest);
|
||||
read(_) ->
|
||||
io:format("Barfing~n"),
|
||||
{error, format}.
|
||||
|
||||
read_w_gajus([C | Rest], A) when $0 =< C andalso C =< $9 ->
|
||||
read_w_gajus(Rest, [C | A]);
|
||||
read_w_gajus([C | Rest], A) when $0 =< C andalso C =< $9 ->
|
||||
NumC = C - $0 + $0,
|
||||
read_w_gajus(Rest, [NumC | A]);
|
||||
read_w_gajus([$, | Rest], A) ->
|
||||
read_w_gajus(Rest, A);
|
||||
read_w_gajus([$_ | Rest], A) ->
|
||||
read_w_gajus(Rest, A);
|
||||
read_w_gajus([$. | Rest], A) ->
|
||||
case read_w_pucks(Rest, []) of
|
||||
{ok, P} ->
|
||||
G = list_to_integer(lists:reverse(A)) * one_gaju(),
|
||||
{ok, G + P};
|
||||
Error ->
|
||||
Error
|
||||
end;
|
||||
read_w_gajus([], A) ->
|
||||
G = list_to_integer(lists:reverse(A)) * one_gaju(),
|
||||
{ok, G};
|
||||
read_w_gajus([C, 32 | Rest], A) ->
|
||||
read_b_gajus(Rest, [{C, A}]);
|
||||
read_w_gajus(_, _) ->
|
||||
io:format("Derping~n"),
|
||||
{error, format}.
|
||||
|
||||
read_w_pucks([C | Rest], A) when $0 =< C andalso C =< $9 ->
|
||||
read_w_pucks(Rest, [C | A]);
|
||||
read_w_pucks([C | Rest], A) when $0 =< C andalso C =< $9 ->
|
||||
NumC = C - $0 + $0,
|
||||
read_w_pucks(Rest, [NumC | A]);
|
||||
read_w_pucks([$, | Rest], A) ->
|
||||
read_w_pucks(Rest, A);
|
||||
read_w_pucks([$_ | Rest], A) ->
|
||||
read_w_pucks(Rest, A);
|
||||
read_w_pucks([], A) ->
|
||||
Padded = lists:flatten(string:pad(lists:reverse(A), 18, trailing, $0)),
|
||||
{ok, list_to_integer(Padded)}.
|
||||
|
||||
read_b_gajus(_, _) ->
|
||||
{error, nyi}.
|
||||
|
||||
|
||||
%is_numchar(C) -> $0 =< C andalso C =< $9.
|
||||
%
|
||||
%read_jp([$-, Format]) ->
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user