Skip to content

Commit

Permalink
Merge pull request #16 from zeek0x/zeek0x/feature/add_print_format
Browse files Browse the repository at this point in the history
Add print option to moyo_string:to_string/2.
yaoshimax authored Aug 3, 2020
2 parents ffea672 + 471e6c9 commit 6dbd3cd
Showing 3 changed files with 58 additions and 42 deletions.
26 changes: 12 additions & 14 deletions doc/moyo_string.md
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ Copyright (c) 2013-2014 DWANGO Co., Ltd. All Rights Reserved.


<pre><code>
encode_option() = {float_format, [<a href="#type-float_format_option">float_format_option()</a>]}
encode_option() = print | {float_format, [<a href="#type-float_format_option">float_format_option()</a>]}
</code></pre>


@@ -39,7 +39,7 @@ float_format_option() = {scientific, Decimals::0..249} | {decimals, Decimals::0.
## Function Index ##


<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#format-2">format/2</a></td><td>指定されたフォーマットの文字列を生成して返す.</td></tr><tr><td valign="top"><a href="#is_ascii_string-1">is_ascii_string/1</a></td><td>引数の値がASCII文字列であるかどうかを判定する.</td></tr><tr><td valign="top"><a href="#is_iodata-1">is_iodata/1</a></td><td>引数の値が<code>iodata</code>であるかどうかを判定する.</td></tr><tr><td valign="top"><a href="#is_iolist-1">is_iolist/1</a></td><td>引数の値が<code>iolist</code>であるかどうかを判定する.</td></tr><tr><td valign="top"><a href="#to_string-1">to_string/1</a></td><td>Erlangの項を文字列(数値のリスト)に変換する.</td></tr><tr><td valign="top"><a href="#to_string-2">to_string/2</a></td><td>Erlangの項を文字列(数値のリスト)に、指定されたオプションに従って変換する.</td></tr></table>
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#format-2">format/2</a></td><td>指定されたフォーマットの文字列を生成して返す.</td></tr><tr><td valign="top"><a href="#is_ascii_string-1">is_ascii_string/1</a></td><td>引数の値がASCII文字列であるかどうかを判定する.</td></tr><tr><td valign="top"><a href="#is_iodata-1">is_iodata/1</a></td><td>引数の値が<code>iodata</code>であるかどうかを判定する.</td></tr><tr><td valign="top"><a href="#is_iolist-1">is_iolist/1</a></td><td>引数の値が<code>iolist</code>であるかどうかを判定する.</td></tr><tr><td valign="top"><a href="#to_string-1">to_string/1</a></td><td>Equivalent to <a href="#to_string-2"><tt>to_string(V, [])</tt></a>.</td></tr><tr><td valign="top"><a href="#to_string-2">to_string/2</a></td><td>Erlangの項を文字列(数値のリスト)に、指定されたオプションに従って変換する.</td></tr></table>


<a name="functions"></a>
@@ -104,22 +104,16 @@ See: [`http://www.erlang.org/doc/reference_manual/typespec.html`](http://www.erl

### to_string/1 ###

<pre><code>
to_string(V::term()) -&gt; string()
</code></pre>
<br />
`to_string(V) -> any()`

Erlangの項を文字列(数値のリスト)に変換する

入力値が非負の数値リストの場合は、変換は行われずにそのまま返される。<br />
ユニコード値のリストから、UTF-8のリストへ変換したい場合等は unicode モジュールを使用する必要がある。
Equivalent to [`to_string(V, [])`](#to_string-2).

<a name="to_string-2"></a>

### to_string/2 ###

<pre><code>
to_string(V::term(), Options::[<a href="#type-encode_option">encode_option()</a>]) -&gt; string()
to_string(V::term(), Rest::[<a href="#type-encode_option">encode_option()</a>]) -&gt; string()
</code></pre>
<br />

@@ -128,6 +122,10 @@ Erlangの項を文字列(数値のリスト)に、指定されたオプション
入力値が非負の数値リストの場合は、変換は行われずにそのまま返される。<br />
ユニコード値のリストから、UTF-8のリストへ変換したい場合等は unicode モジュールを使用する必要がある。<br />

入力値がタプルや深いリストならば `print` オプションを指定することで<br />
io_lib:format/2 のフォーマット`"~p"`に従った表現で変換することができる。<br />
デフォルト値は`"~w"`。<br />

入力値が浮動小数点数ならば float_to_list/2 で指定できるオプション<br />
[{scientific, Decimals} | {decimals, Decimals} | compact]<br />
を利用して変換方式を指定することができる。<br />
@@ -136,10 +134,10 @@ Erlangの項を文字列(数値のリスト)に、指定されたオプション

```
> moyo_string:to_string(12.34, [{float_format, [{scientific, 6}]}]).
<<"1.234000e+01">>
"1.234000e+01"
> moyo_string:to_string(12.34, [{float_format, [{decimals, 6}]}]).
<<"12.340000">>
"12.340000"
> moyo_string:to_string(12.34, [{float_format, [{decimals, 6}, compact]}]).
<<"12.34">>
"12.34"
```

64 changes: 36 additions & 28 deletions src/moyo_string.erl
Original file line number Diff line number Diff line change
@@ -31,58 +31,46 @@
| {decimals, Decimals :: 0..253}
| compact.

-type encode_option() :: {float_format, [float_format_option()]}.
-type encode_option() :: print | {float_format, [float_format_option()]}.

%%----------------------------------------------------------------------------------------------------------------------
%% Exported Functions
%%----------------------------------------------------------------------------------------------------------------------

%% @doc Erlangの項を文字列(数値のリスト)に変換する
%%
%% 入力値が非負の数値リストの場合は、変換は行われずにそのまま返される。<br />
%% ユニコード値のリストから、UTF-8のリストへ変換したい場合等は unicode モジュールを使用する必要がある。
-spec to_string(term()) -> string().
to_string(V) when is_binary(V) -> binary_to_list(V);
to_string(V) when is_atom(V) -> atom_to_list(V);
to_string(V) when is_integer(V) -> integer_to_list(V);
to_string(V) when is_float(V) -> float_to_list(V);
to_string(V) when is_function(V) -> erlang:fun_to_list(V);
to_string(V) when is_pid(V) -> erlang:pid_to_list(V);
to_string(V) when is_port(V) -> erlang:port_to_list(V);
to_string(V) when is_reference(V)-> erlang:ref_to_list(V);
to_string(V) when is_list(V) ->
IsNonNegInteger = fun (C) -> is_integer(C) andalso C >= 0 end,
case lists:all(IsNonNegInteger, V) of
true -> V;
false -> lists:flatten(io_lib:format("~w", [V]))
end;
%% @equiv to_string(V, [])
to_string(V) ->
lists:flatten(io_lib:format("~w", [V])).
to_string(V, []).

%% @doc Erlangの項を文字列(数値のリスト)に、指定されたオプションに従って変換する
%%
%% 入力値が非負の数値リストの場合は、変換は行われずにそのまま返される。<br />
%% ユニコード値のリストから、UTF-8のリストへ変換したい場合等は unicode モジュールを使用する必要がある。<br />
%%
%% 入力値がタプルや深いリストならば `print' オプションを指定することで<br />
%% io_lib:format/2 のフォーマット`"~p"'に従った表現で変換することができる。<br />
%% デフォルト値は`"~w"'。<br />
%%
%% 入力値が浮動小数点数ならば float_to_list/2 で指定できるオプション<br />
%% [{scientific, Decimals} | {decimals, Decimals} | compact]<br />
%% を利用して変換方式を指定することができる。<br />
%% {scientific, Decimals} と {decimals, Decimals} が同時に指定された場合は、最後に指定されたものが採用される。<br />
%% 例:
%% ```
%% > moyo_string:to_string(12.34, [{float_format, [{scientific, 6}]}]).
%% <<"1.234000e+01">>
%% "1.234000e+01"
%% > moyo_string:to_string(12.34, [{float_format, [{decimals, 6}]}]).
%% <<"12.340000">>
%% "12.340000"
%% > moyo_string:to_string(12.34, [{float_format, [{decimals, 6}, compact]}]).
%% <<"12.34">>
%% "12.34"
%% '''
-spec to_string(term(), [encode_option()]) -> string().
to_string(V, _Options = []) ->
to_string(V);
to_string(V, [{float_format, FloatFormatOptions} | _Rest]) when is_float(V) ->
to_string(V, []) ->
to_string_impl(V, "~w");
to_string(V, [print | _]) ->
to_string_impl(V, "~p");
to_string(V, [{float_format, FloatFormatOptions} | _]) when is_float(V) ->
float_to_list(V, FloatFormatOptions);
to_string(V, [_Option | Rest]) ->
to_string(V, [_ | Rest]) ->
to_string(V, Rest).

%% @doc 指定されたフォーマットの文字列を生成して返す.
@@ -127,3 +115,23 @@ is_iodata(X) -> is_binary(X) orelse is_iolist(X).
is_iolist_element(X) when is_binary(X) -> true;
is_iolist_element(X) when is_integer(X) andalso (0 =< X andalso X =< 255) -> true;
is_iolist_element(X) -> is_iolist(X).

%% @private
%% @doc Erlangの項を文字列(数値のリスト)に変換する
-spec to_string_impl(term(), io:format()) -> string().
to_string_impl(V, _) when is_atom(V) -> atom_to_list(V);
to_string_impl(V, _) when is_binary(V) -> binary_to_list(V);
to_string_impl(V, _) when is_float(V) -> float_to_list(V);
to_string_impl(V, _) when is_integer(V) -> integer_to_list(V);
to_string_impl(V, _) when is_pid(V) -> pid_to_list(V);
to_string_impl(V, _) when is_function(V) -> erlang:fun_to_list(V);
to_string_impl(V, _) when is_port(V) -> erlang:port_to_list(V);
to_string_impl(V, _) when is_reference(V) -> erlang:ref_to_list(V);
to_string_impl(V, IoLibFormat) when is_list(V) ->
IsNonNegInteger = fun (C) -> is_integer(C) andalso C >= 0 end,
case lists:all(IsNonNegInteger, V) of
true -> V;
false -> format(IoLibFormat, [V])
end;
to_string_impl(V, IoLibFormat) ->
format(IoLibFormat, [V]).
10 changes: 10 additions & 0 deletions test/moyo_string_tests.erl
Original file line number Diff line number Diff line change
@@ -64,6 +64,16 @@ to_string_test_() ->
Expected2 = "{{1,2,3},<0.1.0>,[[[[[<<97,98,99>>]],{hello}]]]}",
?assertEqual(Expected2, moyo_string:to_string(Input2))
end},
{"複雑なデータ構造をプリント表現に変換可能",
fun() ->
Input1 = [{1,2,3}, c:pid(0,1,0), [[[[[<<"abc">>]], {hello}]]]],
Expected1 = "[{1,2,3},<0.1.0>,[[[[[<<\"abc\">>]],{hello}]]]]",
?assertEqual(Expected1, moyo_string:to_string(Input1, [print])),

Input2 = {{1,2,3}, c:pid(0,1,0), [[[[[<<"abc">>]], {hello}]]]},
Expected2 = "{{1,2,3},<0.1.0>,[[[[[<<\"abc\">>]],{hello}]]]}",
?assertEqual(Expected2, moyo_string:to_string(Input2, [print]))
end},
{"関数を文字列に変換",
fun () ->
Input = fun () -> ok end,

0 comments on commit 6dbd3cd

Please sign in to comment.