1 |
|
-module(mongoose_graphql_scalar). |
2 |
|
-export([input/2, output/2]). |
3 |
|
-ignore_xref([input/2, output/2]). |
4 |
|
|
5 |
|
-include_lib("jid/include/jid.hrl"). |
6 |
|
|
7 |
|
-spec input(Type, Value) -> {ok, Coerced} | {error, Reason} |
8 |
|
when |
9 |
|
Type :: binary(), |
10 |
|
Value :: binary() | pos_integer(), |
11 |
|
Coerced :: any(), |
12 |
|
Reason :: term(). |
13 |
117 |
input(<<"DateTime">>, DT) -> binary_to_microseconds(DT); |
14 |
27 |
input(<<"XmlElement">>, Value) -> exml:parse(Value); |
15 |
1041 |
input(<<"JID">>, Jid) -> jid_from_binary(Jid); |
16 |
453 |
input(<<"BareJID">>, Jid) -> bare_jid_from_binary(Jid); |
17 |
68 |
input(<<"FullJID">>, Jid) -> full_jid_from_binary(Jid); |
18 |
100 |
input(<<"UserName">>, User) -> user_from_binary(User); |
19 |
23 |
input(<<"RoomName">>, Room) -> room_from_binary(Room); |
20 |
450 |
input(<<"DomainName">>, Domain) -> domain_from_binary(Domain); |
21 |
132 |
input(<<"ResourceName">>, Res) -> resource_from_binary(Res); |
22 |
31 |
input(<<"NodeName">>, Node) -> node_from_binary(Node); |
23 |
100 |
input(<<"NonEmptyString">>, Value) -> non_empty_string_to_binary(Value); |
24 |
153 |
input(<<"PosInt">>, Value) -> validate_pos_integer(Value); |
25 |
5 |
input(<<"NonNegInt">>, Value) -> validate_non_neg_integer(Value); |
26 |
|
input(Ty, V) -> |
27 |
:-( |
error_logger:info_report({coercing_generic_scalar, Ty, V}), |
28 |
:-( |
{ok, V}. |
29 |
|
|
30 |
|
-spec output(Type, Value) -> {ok, Coerced} | {error, Reason} |
31 |
|
when |
32 |
|
Type :: binary(), |
33 |
|
Value :: binary() | pos_integer(), |
34 |
|
Coerced :: any(), |
35 |
|
Reason :: term(). |
36 |
114 |
output(<<"DateTime">>, DT) -> {ok, microseconds_to_binary(DT)}; |
37 |
59 |
output(<<"XmlElement">>, Elem) -> {ok, exml:to_binary(Elem)}; |
38 |
346 |
output(<<"JID">>, Jid) -> {ok, jid:to_binary(Jid)}; |
39 |
1 |
output(<<"UserName">>, User) -> {ok, User}; |
40 |
20 |
output(<<"DomainName">>, Domain) -> {ok, Domain}; |
41 |
5 |
output(<<"ResourceName">>, Res) -> {ok, Res}; |
42 |
:-( |
output(<<"NonEmptyString">>, Value) -> binary_to_non_empty_string(Value); |
43 |
8 |
output(<<"PosInt">>, Value) -> validate_pos_integer(Value); |
44 |
81 |
output(<<"NonNegInt">>, Value) -> validate_non_neg_integer(Value); |
45 |
|
output(Ty, V) -> |
46 |
35 |
error_logger:info_report({output_generic_scalar, Ty, V}), |
47 |
35 |
{ok, V}. |
48 |
|
|
49 |
|
jid_from_binary(Value) -> |
50 |
1041 |
case jid:from_binary(Value) of |
51 |
|
error -> |
52 |
19 |
{error, failed_to_parse_jid}; |
53 |
|
#jid{luser = <<>>} -> |
54 |
4 |
{error, jid_without_local_part}; |
55 |
|
Jid -> |
56 |
1018 |
{ok, Jid} |
57 |
|
end. |
58 |
|
|
59 |
|
bare_jid_from_binary(Value) -> |
60 |
453 |
case jid:from_binary(Value) of |
61 |
|
error -> |
62 |
3 |
{error, failed_to_parse_jid}; |
63 |
|
#jid{luser = <<>>} -> |
64 |
2 |
{error, jid_without_local_part}; |
65 |
|
Jid = #jid{lresource = <<>>} -> |
66 |
445 |
{ok, Jid}; |
67 |
|
#jid{} -> |
68 |
3 |
{error, jid_with_resource} |
69 |
|
end. |
70 |
|
|
71 |
|
full_jid_from_binary(Value) -> |
72 |
68 |
case jid:from_binary(Value) of |
73 |
|
error -> |
74 |
:-( |
{error, failed_to_parse_jid}; |
75 |
|
#jid{luser = <<>>} -> |
76 |
:-( |
{error, jid_without_local_part}; |
77 |
|
#jid{lresource = <<>>} -> |
78 |
15 |
{error, jid_without_resource}; |
79 |
|
Jid -> |
80 |
53 |
{ok, Jid} |
81 |
|
end. |
82 |
|
|
83 |
|
user_from_binary(<<>>) -> |
84 |
3 |
{error, empty_user_name}; |
85 |
|
user_from_binary(Value) -> |
86 |
97 |
case jid:nodeprep(Value) of |
87 |
|
error -> |
88 |
3 |
{error, failed_to_parse_user_name}; |
89 |
|
User -> |
90 |
94 |
{ok, User} |
91 |
|
end. |
92 |
|
|
93 |
|
room_from_binary(<<>>) -> |
94 |
1 |
{error, empty_room_name}; |
95 |
|
room_from_binary(Value) -> |
96 |
22 |
case jid:nodeprep(Value) of |
97 |
|
error -> |
98 |
:-( |
{error, failed_to_parse_room_name}; |
99 |
|
Room -> |
100 |
22 |
{ok, Room} |
101 |
|
end. |
102 |
|
|
103 |
|
domain_from_binary(<<>>) -> |
104 |
2 |
{error, empty_domain_name}; |
105 |
|
domain_from_binary(Value) -> |
106 |
448 |
case jid:nameprep(Value) of |
107 |
|
error -> |
108 |
2 |
{error, failed_to_parse_domain_name}; |
109 |
|
Domain -> |
110 |
446 |
{ok, Domain} |
111 |
|
end. |
112 |
|
|
113 |
|
resource_from_binary(<<>>) -> |
114 |
7 |
{error, empty_resource_name}; |
115 |
|
resource_from_binary(Value) -> |
116 |
125 |
case jid:resourceprep(Value) of |
117 |
|
error -> |
118 |
1 |
{error, failed_to_parse_resource_name}; |
119 |
|
Res -> |
120 |
124 |
{ok, Res} |
121 |
|
end. |
122 |
|
|
123 |
|
node_from_binary(<<>>) -> |
124 |
4 |
{error, empty_node_name}; |
125 |
|
node_from_binary(NodeName) -> |
126 |
27 |
case string:lexemes(binary_to_list(NodeName), "@") of |
127 |
|
[_Name, _Host] -> |
128 |
21 |
{ok, binary_to_atom(NodeName)}; |
129 |
|
["self"] -> |
130 |
2 |
{ok, node()}; |
131 |
|
_ -> |
132 |
4 |
{error, incorrect_node_name} |
133 |
|
end. |
134 |
|
|
135 |
|
binary_to_microseconds(DT) -> |
136 |
117 |
case mod_mam_utils:maybe_microseconds(DT) of |
137 |
|
undefined -> |
138 |
12 |
{error, failed_to_parse_datetime}; |
139 |
|
Microseconds -> |
140 |
105 |
{ok, Microseconds} |
141 |
|
end. |
142 |
|
|
143 |
|
non_empty_string_to_binary(<<>>) -> |
144 |
7 |
{error, "Given string is empty"}; |
145 |
|
non_empty_string_to_binary(String) -> |
146 |
93 |
{ok, String}. |
147 |
|
|
148 |
|
binary_to_non_empty_string(<<>>) -> |
149 |
:-( |
{error, "Empty binary cannot be converted to NonEmptyString"}; |
150 |
|
binary_to_non_empty_string(Val) -> |
151 |
:-( |
{ok, Val}. |
152 |
|
|
153 |
|
validate_pos_integer(PosInt) when is_integer(PosInt), PosInt > 0 -> |
154 |
145 |
{ok, PosInt}; |
155 |
|
validate_pos_integer(_Value) -> |
156 |
16 |
{error, "Value is not a positive integer"}. |
157 |
|
|
158 |
|
validate_non_neg_integer(NonNegInt) when is_integer(NonNegInt), NonNegInt >= 0 -> |
159 |
84 |
{ok, NonNegInt}; |
160 |
|
validate_non_neg_integer(_Value) -> |
161 |
2 |
{error, "Value is not a non-negative integer"}. |
162 |
|
|
163 |
|
microseconds_to_binary(Microseconds) -> |
164 |
114 |
Opts = [{offset, "Z"}, {unit, microsecond}], |
165 |
114 |
list_to_binary(calendar:system_time_to_rfc3339(Microseconds, Opts)). |