_site/cover/scran_result.COVER.html

1 %% Copyright (c) 2023 Peter Morgan <peter.james.morgan@gmail.com>
2 %%
3 %% Licensed under the Apache License, Version 2.0 (the "License");
4 %% you may not use this file except in compliance with the License.
5 %% You may obtain a copy of the License at
6 %%
7 %% http://www.apache.org/licenses/LICENSE-2.0
8 %%
9 %% Unless required by applicable law or agreed to in writing, software
10 %% distributed under the License is distributed on an "AS IS" BASIS,
11 %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 %% See the License for the specific language governing permissions and
13 %% limitations under the License.
14
15
16 %% @doc Parser combinators that map the result.
17
18 -module(scran_result).
19
20
21 -feature(maybe_expr, enable).
22
23
24 -export([ignore/1]).
25 -export([into_atom/1]).
26 -export([into_bits/2]).
27 -export([into_existing_atom/1]).
28 -export([into_integer/1]).
29 -export([into_integer/2]).
30 -export([into_map/1]).
31 -export([into_snake_case/1]).
32 -export([into_tuple/1]).
33 -export([kv/2]).
34 -import(scran_combinator, [map_result/2]).
35
36
37 %% @doc The parser result is converted into a 2-tuple with the supplied
38 %% key as the first element.
39
40 -spec kv(any(), scran:parser(I, O)) -> scran:parser(I, {any(), O}).
41
42 kv(Key, Parser) ->
43 19 fun
44 (Input) ->
45 17 (map_result(Parser, kv(Key)))(Input)
46 end.
47
48 kv(Key) ->
49 17 fun
50 (Value) ->
51 15 {Key, Value}
52 end.
53
54
55 %% @doc The parser result is converted into snake case.
56
57 -spec into_snake_case(
58 scran:parser(unicode:chardata(),
59 unicode:chardata())) ->
60 scran:parser(unicode:chardata(),
61 unicode:chardata()).
62
63 into_snake_case(Parser) ->
64 9 fun
65 (Input) ->
66 9 (map_result(
67 Parser,
68 fun
69 (Result) when is_binary(Result) ->
70 4 snake_case(Result);
71
72 (Result) when is_list(Result) ->
73 4 binary_to_list(snake_case(Result))
74
75 end))(Input)
76 end.
77
78
79 -spec snake_case(unicode:chardata()) -> binary().
80
81 snake_case(Result) ->
82 8 iolist_to_binary(
83 lists:join(
84 "_",
85 string:split(
86 string:lowercase(Result),
87 " ",
88 all))).
89
90
91 %% @doc The parser result is converted into an atom.
92
93 -spec into_atom(
94 scran:parser(unicode:chardata(),
95 unicode:chardata())) ->
96 scran:parser(unicode:chardata(),
97 atom()).
98
99 into_atom(Parser) ->
100 8 fun
101 (Input) ->
102 26 (map_result(
103 Parser,
104 fun
105 (Result) when is_binary(Result) ->
106 1 binary_to_atom(Result);
107
108 (Result) when is_list(Result) ->
109 18 list_to_atom(Result)
110 end))(Input)
111 end.
112
113
114 %% @doc The parser result is converted into an existing atom.
115
116 -spec into_existing_atom(
117 scran:parser(unicode:chardata(),
118 unicode:chardata())) ->
119 scran:parser(unicode:chardata(),
120 atom()).
121
122 into_existing_atom(Parser) ->
123 3 fun
124 (Input) ->
125 3 try
126 3 (map_result(
127 Parser,
128 fun
129 (Result) when is_binary(Result) ->
130 2 binary_to_existing_atom(Result);
131
132 (Result) when is_list(Result) ->
133 1 list_to_existing_atom(Result)
134 end))(Input)
135
136 catch
137 error:badarg ->
138 1 nomatch
139 end
140 end.
141
142
143 %% @doc When the parser result is a list of key/value tuples it is
144 %% converted into an Erlang map.
145
146 -spec into_map(scran:parser(I, [{K, V}])) -> scran:parser(I, #{K => V}).
147
148 into_map(Parser) ->
149 13 fun
150 (Input) ->
151 16 (map_result(Parser, fun maps:from_list/1))(Input)
152 end.
153
154
155 %% @doc When the parser result is a list of terms it is converted into
156 %% a tuple.
157
158 -spec into_tuple(scran:parser(I, [term()])) -> scran:parser(I, tuple()).
159
160 into_tuple(Parser) ->
161 24 fun
162 (Input) ->
163 43 (map_result(Parser, fun erlang:list_to_tuple/1))(Input)
164 end.
165
166
167 %% @doc The parser result is mapped into a bitstring of the supplied
168 %% length.
169
170 -spec into_bits(scran:parser(I, integer()),
171 pos_integer()) -> scran:parser(I, bitstring()).
172
173 into_bits(Parser, Bits) ->
174 6 fun
175 (Input) ->
176 6 (map_result(
177 Parser,
178 fun
179 (Result) when is_integer(Result) ->
180 4 <<Result:Bits>>
181 end))(Input)
182 end.
183
184
185 %% @doc Convert the parser result into a base 10 integer.
186
187 into_integer(Parser) ->
188 15 ?FUNCTION_NAME(Parser, 10).
189
190
191 %% @doc Convert the parser result into an integer with the supplied
192 %% base.
193
194 into_integer(Parser, Base) ->
195 15 fun
196 (Input) ->
197 24 (map_result(
198 Parser,
199 fun
200 (Result) when is_binary(Result) ->
201 1 binary_to_integer(Result, Base);
202
203 (Result) when is_list(Result) ->
204 20 list_to_integer(Result, Base)
205 end))(Input)
206 end.
207
208
209 %% @doc Ignore the result of the embedded parser.
210
211 -spec ignore(scran:parser()) -> scran:parser().
212
213 ignore(Parser) ->
214 2 map_result(Parser,
215 fun
216 (_) ->
217 1 none
218 end).
Line Hits Source