WIP: omg stuff
This commit is contained in:
parent
e4e6e35bf8
commit
beed46a38b
@ -4,7 +4,8 @@
|
||||
|
||||
-module(hz_format).
|
||||
|
||||
-export([price/1, price/2, price/3, price/4, % read_price/1,
|
||||
-export([price/1, price/2, price/3, price/4,
|
||||
read/1,
|
||||
price_to_string/1, string_to_price/1]).
|
||||
|
||||
-spec price(Pucks) -> Formatted
|
||||
@ -19,9 +20,9 @@ price(Pucks) ->
|
||||
|
||||
|
||||
-spec price(Style, Pucks) -> Formatted
|
||||
when Style :: us | ch | jp | {Separator, Period},
|
||||
Separator :: $, | $. | $_,
|
||||
Period :: 3 | 4,
|
||||
when Style :: us | ch | jp | {Separator, Myriad},
|
||||
Separator :: $, | $. | $_,
|
||||
Myriad :: 3 | 4,
|
||||
Pucks :: integer(),
|
||||
Formatted :: string().
|
||||
%% @doc
|
||||
@ -33,42 +34,42 @@ price(Style, Pucks) ->
|
||||
|
||||
|
||||
-spec price(Unit, Style, Pucks) -> Formatted
|
||||
when Unit :: gaju | puck,
|
||||
Style :: us | ch | jp | {Separator, Period},
|
||||
when Unit :: gaju | puck,
|
||||
Style :: us | ch | jp | {Separator, Myriad},
|
||||
Separator :: $, | $. | $_,
|
||||
Period :: 3 | 4,
|
||||
Pucks :: integer(),
|
||||
Formatted :: string().
|
||||
Myriad :: 3 | 4,
|
||||
Pucks :: integer(),
|
||||
Formatted :: string().
|
||||
%% @doc
|
||||
%% A simplified format function covering the most common formats desired.
|
||||
%%
|
||||
%% ```
|
||||
|
||||
price(gaju, us, Pucks) ->
|
||||
wetsern($,, $., 3, all, Pucks);
|
||||
western($,, $., 3, all, Pucks);
|
||||
price(puck, us, Pucks) ->
|
||||
wetsern($,, 3, Pucks);
|
||||
western($,, 3, Pucks);
|
||||
price(gaju, ch, Pucks) ->
|
||||
wetsern($., $,, 3, all, Pucks);
|
||||
western($., $,, 3, all, Pucks);
|
||||
price(puck, ch, Pucks) ->
|
||||
wetsern($,, 3, Pucks);
|
||||
western($,, 3, Pucks);
|
||||
price(Unit, jp, Pucks) ->
|
||||
jp(Unit, all, Pucks);
|
||||
price(gaju, {$., Period}, Pucks) ->
|
||||
wetsern($., $,, Period, all, Pucks);
|
||||
price(gaju, {Separator, Period}, Pucks) ->
|
||||
wetsern(Separator, $., Period, all, Pucks);
|
||||
price(puck, {Separator, Period}, Pucks) ->
|
||||
wetsern(Separator, Period, Pucks).
|
||||
price(gaju, {$., Myriad}, Pucks) ->
|
||||
western($., $,, Myriad, all, Pucks);
|
||||
price(gaju, {Separator, Myriad}, Pucks) ->
|
||||
western(Separator, $., Myriad, all, Pucks);
|
||||
price(puck, {Separator, Myriad}, Pucks) ->
|
||||
western(Separator, Myriad, Pucks).
|
||||
|
||||
|
||||
|
||||
-spec price(Unit, Style, Precision, Pucks) -> Serialized
|
||||
when Unit :: gaju | puck,
|
||||
Style :: us | ch | jp | {Separator, Period},
|
||||
Style :: us | ch | jp | {Separator, Myriad},
|
||||
Precision :: all | 0..18,
|
||||
Separator :: $, | $. | $_,
|
||||
Period :: 3 | 4,
|
||||
Myriad :: 3 | 4,
|
||||
Pucks :: integer(),
|
||||
Serialized :: string().
|
||||
%% @doc
|
||||
@ -110,36 +111,47 @@ price(puck, {Separator, Period}, Pucks) ->
|
||||
%% '''
|
||||
|
||||
price(gaju, us, Precision, Pucks) ->
|
||||
wetsern($,, $., 3, Precision, Pucks);
|
||||
western($,, $., 3, Precision, Pucks);
|
||||
price(gaju, ch, Precision, Pucks) ->
|
||||
wetsern($., $,, 3, Precision, Pucks);
|
||||
western($., $,, 3, Precision, Pucks);
|
||||
price(gaju, jp, Precision, Pucks) ->
|
||||
jp(gaju, Precision, Pucks);
|
||||
price(gaju, {$., Period}, Precision, Pucks) ->
|
||||
wetsern($., $,, Period, Precision, Pucks);
|
||||
price(gaju, {Separator, Period}, Precision, Pucks) ->
|
||||
wetsern(Separator, $., Period, Precision, Pucks);
|
||||
price(gaju, {$., Myriad}, Precision, Pucks) ->
|
||||
western($., $,, Myriad, Precision, Pucks);
|
||||
price(gaju, {Separator, Myriad}, Precision, Pucks) ->
|
||||
western(Separator, $., Myriad, Precision, Pucks);
|
||||
price(puck, us, _, Pucks) ->
|
||||
wetsern($,, 3, Pucks);
|
||||
western($,, 3, Pucks);
|
||||
price(puck, ch, _, Pucks) ->
|
||||
wetsern($., 3, Pucks);
|
||||
western($., 3, Pucks);
|
||||
price(puck, jp, _, Pucks) ->
|
||||
jp(puck, all, Pucks);
|
||||
price(puck, {Separator, Period}, _, Pucks) ->
|
||||
wetsern(Separator, Period, Pucks).
|
||||
price(puck, {Separator, Myriad}, _, Pucks) ->
|
||||
western(Separator, Myriad, Pucks).
|
||||
|
||||
|
||||
|
||||
|
||||
wetsern(Separator, Period, Pucks) ->
|
||||
western(Separator, Myriad, Pucks) when Pucks >= 0 ->
|
||||
western2(Separator, Myriad, Pucks);
|
||||
western(Separator, Myriad, Pucks) when Pucks < 0 ->
|
||||
[$- | western2(Separator, Myriad, Pucks * -1)].
|
||||
|
||||
western2(Separator, Myriad, Pucks) ->
|
||||
P = lists:reverse(integer_to_list(Pucks)),
|
||||
[puck_mark() | separate(Separator, Period, P)].
|
||||
[puck_mark() | separate(Separator, Myriad, P)].
|
||||
|
||||
|
||||
wetsern(Separator, _, Period, 0, Pucks) ->
|
||||
western(Separator, Break, Myriad, Precision, Pucks) when Pucks >= 0 ->
|
||||
western2(Separator, Break, Myriad, Precision, Pucks);
|
||||
western(Separator, Break, Myriad, Precision, Pucks) when Pucks < 0 ->
|
||||
[$- | western2(Separator, Break, Myriad, Precision, Pucks)].
|
||||
|
||||
|
||||
western2(Separator, _, Myriad, 0, Pucks) ->
|
||||
G = lists:reverse(integer_to_list(Pucks div one_gaju())),
|
||||
[gaju_mark() | separate(Separator, Period, G)];
|
||||
wetsern(Separator, Break, Period, Precision, Pucks) ->
|
||||
[gaju_mark() | separate(Separator, Myriad, G)];
|
||||
western2(Separator, Break, Myriad, Precision, Pucks) ->
|
||||
SP = integer_to_list(Pucks),
|
||||
Length = length(SP),
|
||||
Over18 = Length > 18,
|
||||
@ -147,19 +159,19 @@ wetsern(Separator, Break, Period, Precision, Pucks) ->
|
||||
case {Over18, NoPucks} of
|
||||
{true, true} ->
|
||||
Gs = lists:reverse(lists:sublist(SP, Length - 18)),
|
||||
[gaju_mark() | separate(Separator, Period, Gs)];
|
||||
[gaju_mark() | separate(Separator, Myriad, Gs)];
|
||||
{true, false} ->
|
||||
{PChars, GChars} = lists:split(18, lists:reverse(SP)),
|
||||
H = [gaju_mark() | separate(Separator, Period, GChars)],
|
||||
H = [gaju_mark() | separate(Separator, Myriad, GChars)],
|
||||
{P, E} = decimal_pucks(Precision, lists:reverse(PChars)),
|
||||
T = lists:reverse(separate(Separator, Period, P)),
|
||||
T = lists:reverse(separate(Separator, Myriad, P)),
|
||||
lists:flatten([H, Break, T, E]);
|
||||
{false, true} ->
|
||||
[gaju_mark(), $0];
|
||||
{false, false} ->
|
||||
PChars = lists:flatten(string:pad(SP, 18, leading, $0)),
|
||||
{P, E} = decimal_pucks(Precision, PChars),
|
||||
T = lists:reverse(separate(Separator, Period, P)),
|
||||
T = lists:reverse(separate(Separator, Myriad, P)),
|
||||
lists:flatten([gaju_mark(), $0, Break, T, E])
|
||||
end.
|
||||
|
||||
@ -189,24 +201,44 @@ separate(S, P, N, [H | T], A) ->
|
||||
separate(S, P, N + 1, T, [H | A]).
|
||||
|
||||
|
||||
jp(gaju, 0, Pucks) ->
|
||||
jp(Unit, Precision, Pucks) when Pucks >= 0 ->
|
||||
jp2(Unit, Precision, Pucks);
|
||||
jp(Unit, Precision, Pucks) when Pucks < 0 ->
|
||||
[$-, Formatted = jp2(Unit, Precision, Pucks * -1)].
|
||||
|
||||
jp2(gaju, 0, Pucks) ->
|
||||
G = lists:reverse(integer_to_list(Pucks div one_gaju())),
|
||||
rank4(gaju_mark(), G);
|
||||
jp(gaju, all, Pucks) ->
|
||||
myriad4(gaju_mark(), h, G);
|
||||
jp2(gaju, all, Pucks) ->
|
||||
H = jp(gaju, 0, Pucks),
|
||||
T = jp(puck, all, Pucks rem one_gaju()),
|
||||
P = lists:flatten(string:pad(integer_to_list(Pucks rem one_gaju()), 18, leading, $0),
|
||||
T = myriad4("", l, lists:reverse(P)),
|
||||
lists:flatten([H, " ", T]);
|
||||
jp(gaju, Precision, Pucks) ->
|
||||
jp2(gaju, Precision, Pucks) ->
|
||||
H = jp(gaju, 0, Pucks),
|
||||
T = jp(puck, Precision, Pucks rem one_gaju()),
|
||||
P = lists:flatten(string:pad(integer_to_list(Pucks rem one_gaju()), 18, leading, $0),
|
||||
Digits = min(Precision, 18),
|
||||
T =
|
||||
case length(P) > Digits of
|
||||
true ->
|
||||
[];
|
||||
false ->
|
||||
ReverseP = lists:reverse(lists:sublist(P, Digits)),
|
||||
PuckingString = lists:flatten(string:pad(ReverseP, 18, leading, $0)),
|
||||
case lists:all(fun(C) -> C =:= $0 end, PuckingString) of
|
||||
false -> myriad4(puck_mark(), l, PuckingString);
|
||||
true -> ""
|
||||
end
|
||||
end,
|
||||
T = myriad4("", l, lists:reverse(P)),
|
||||
lists:flatten([H, " ", T]);
|
||||
jp(puck, all, Pucks) ->
|
||||
jp2(puck, all, Pucks) ->
|
||||
P = lists:reverse(integer_to_list(Pucks)),
|
||||
case lists:all(fun(C) -> C =:= $0 end, P) of
|
||||
false -> rank4(puck_mark(), P);
|
||||
false -> myriad4(puck_mark(), h, P);
|
||||
true -> [$0, puck_mark()]
|
||||
end;
|
||||
jp(puck, Precision, Pucks) ->
|
||||
jp2(puck, Precision, Pucks) ->
|
||||
Digits = min(Precision, 18),
|
||||
P = lists:flatten(string:pad(integer_to_list(Pucks), 18, leading, $0)),
|
||||
case length(P) < Digits of
|
||||
@ -215,27 +247,27 @@ jp(puck, Precision, Pucks) ->
|
||||
false ->
|
||||
PuckingString = lists:flatten(string:pad(lists:reverse(lists:sublist(P, Digits)), 18, leading, $0)),
|
||||
case lists:all(fun(C) -> C =:= $0 end, PuckingString) of
|
||||
false -> rank4(puck_mark(), PuckingString);
|
||||
false -> myriad4(puck_mark(), h, PuckingString);
|
||||
true -> [$0, puck_mark()]
|
||||
end
|
||||
end.
|
||||
|
||||
|
||||
rank4(Symbol, [$0, $0, $0, $0 | PT]) ->
|
||||
rank4(ranks(jp), PT, [Symbol]);
|
||||
rank4(Symbol, [P4, $0, $0, $0 | PT]) ->
|
||||
rank4(ranks(jp), PT, [P4, Symbol]);
|
||||
rank4(Symbol, [P4, P3, $0, $0 | PT]) ->
|
||||
rank4(ranks(jp), PT, [P3, P4, Symbol]);
|
||||
rank4(Symbol, [P4, P3, P2, $0 | PT]) ->
|
||||
rank4(ranks(jp), PT, [P2, P3, P4, Symbol]);
|
||||
rank4(Symbol, [P4, P3, P2, P1 | PT]) ->
|
||||
rank4(ranks(jp), PT, [P1, P2, P3, P4, Symbol]);
|
||||
rank4(Symbol, [P4]) ->
|
||||
myriad4(Symbol, Segment, [$0, $0, $0, $0 | PT]) ->
|
||||
rank4(ranks(Segment), PT, [Symbol]);
|
||||
myriad4(Symbol, Segment, [P4, $0, $0, $0 | PT]) ->
|
||||
rank4(ranks(Segment), PT, [P4, Symbol]);
|
||||
myriad4(Symbol, Segment, [P4, P3, $0, $0 | PT]) ->
|
||||
rank4(ranks(Segment), PT, [P3, P4, Symbol]);
|
||||
myriad4(Symbol, Segment, [P4, P3, P2, $0 | PT]) ->
|
||||
rank4(ranks(Segment), PT, [P2, P3, P4, Symbol]);
|
||||
myriad4(Symbol, Segment, [P4, P3, P2, P1 | PT]) ->
|
||||
rank4(ranks(Segment), PT, [P1, P2, P3, P4, Symbol]);
|
||||
myriad4(Symbol, _, [P4]) ->
|
||||
[P4, Symbol];
|
||||
rank4(Symbol, [P4, P3]) ->
|
||||
myriad4(Symbol, _, [P4, P3]) ->
|
||||
[P3, P4, Symbol];
|
||||
rank4(Symbol, [P4, P3, P2]) ->
|
||||
myriad4(Symbol, _, [P4, P3, P2]) ->
|
||||
[P2, P3, P4, Symbol].
|
||||
|
||||
rank4([_ | RT], [$0, $0, $0, $0 | PT], A) ->
|
||||
@ -279,8 +311,11 @@ rank4([RH | _], [P4, P3, P2], A) ->
|
||||
rank4([RH | _], [P4, P3, P2, P1], A) ->
|
||||
[P1, P2, P3, P4, RH | A].
|
||||
|
||||
ranks(jp) ->
|
||||
"万億兆京垓秭穣溝澗正載極".
|
||||
ranks(h) ->
|
||||
"万億兆京垓秭穣溝澗正載極";
|
||||
ranks(l) ->
|
||||
% "曼戌弒俿咳".
|
||||
"満億照鏡咳".
|
||||
|
||||
|
||||
gaju_mark() -> $木.
|
||||
@ -290,6 +325,159 @@ 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(Format) of
|
||||
us -> read(us, Format);
|
||||
ch -> read(ch, Format);
|
||||
jp -> read(jp, Format);
|
||||
Error -> Error
|
||||
end.
|
||||
|
||||
-spec read(Style, Formatted) -> Result
|
||||
when Style :: us | ch | jp | 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(ch, Format) ->
|
||||
read_western($,, Format);
|
||||
read2(jp, Format) ->
|
||||
read_jp(Format);
|
||||
read2(undefined, Format) ->
|
||||
read(Format).
|
||||
|
||||
read_western(Break, [$-, Rest]) ->
|
||||
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.
|
||||
|
||||
is_numchar(C) -> $0 =< C andalso C =< $9.
|
||||
|
||||
read_jp([$-, Format]) ->
|
||||
read_jp_neg(Format);
|
||||
read_jp([$-, Format]) ->
|
||||
read_jp_neg(Format);
|
||||
read_jp(Format) ->
|
||||
read_jp2(Format).
|
||||
|
||||
read_jp_neg(Format) ->
|
||||
case read_jp2(Format) of
|
||||
{ok, Pucks} -> {ok, Pucks * -1};
|
||||
Error -> Error
|
||||
end.
|
||||
|
||||
read_jp2(Format) ->
|
||||
case segment_jp(Format) of
|
||||
{ok, Segments} -> assemble_jp(Segments);
|
||||
Error -> Error
|
||||
end.
|
||||
|
||||
segment_jp(Format) ->
|
||||
case string:split(Format, [gaju_mark()], all) of
|
||||
[Gajus, Pucks] ->
|
||||
case read_segment(Gajus) of
|
||||
{ok,
|
||||
[Gajus] ->
|
||||
case read_segment(Gajus) of
|
||||
{ok, GajuSegments} -> {ok, GajuSegments, ["0"]};
|
||||
Error -> Error
|
||||
end;
|
||||
[] ->
|
||||
{ok, ["0"], ["0"]};
|
||||
_ ->
|
||||
{error, format}
|
||||
end.
|
||||
|
||||
assemble_jp({GajuSegments, PuckSegments}) ->
|
||||
GajuString = lists:flatten(lists:map(fun expand_jp_myriad/1, GajuSegments)),
|
||||
PuckString = lists:flatten(lists:map(fun expand_jp_myriad/1, PuckDegments)),
|
||||
{ok, integer_to_list(lists:append(GajuString, PuckString))}.
|
||||
assemble_jp(PuckSegments) ->
|
||||
PuckString = lists:flatten(lists:map(fun expand_jp_myriad/1, PuckDegments)),
|
||||
{ok, integer_to_list(PuckString)}.
|
||||
|
||||
expand_jp_myriad(String) ->
|
||||
string:pad(String, 4, leading, $0).
|
||||
|
||||
|
||||
lower_jp_numchar(C) when $0 =< C andalso C =< $9 ->
|
||||
C - $0;
|
||||
lower_jp_numchar(C) ->
|
||||
C.
|
||||
|
||||
|
||||
-spec price_to_string(Pucks) -> Gajus
|
||||
when Pucks :: integer(),
|
||||
Gajus :: string().
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user