Skip to content

Commit eb9e1bf

Browse files
committed
type_checkers: decode
1 parent f514be1 commit eb9e1bf

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

src/type_checkers/decode.cr

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# -----------------------------------------------------------------------
2+
# This file is part of MoonScript
3+
#
4+
# MoonSript is free software: you can redistribute it and/or modify
5+
# it under the terms of the GNU General Public License as published by
6+
# the Free Software Foundation, either version 3 of the License, or
7+
# (at your option) any later version.
8+
#
9+
# MoonSript is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License
15+
# along with MoonSript. If not, see <https://www.gnu.org/licenses/>.
16+
#
17+
# Copyright (C) 2025 Krisna Pranav, MoonScript Developers
18+
# -----------------------------------------------------------------------
19+
20+
module MoonScript
21+
class TypeChecker
22+
def check(node : Ast::Decode) : Checkable
23+
type =
24+
resolve node.type
25+
26+
error! :decode_complex_type do
27+
snippet "This type cannot be automatically decoded:", type
28+
29+
snippet(
30+
"Only these types and records containing them cantext be " \
31+
"automatically decoded:",
32+
<<-MINT
33+
Map(String, a)
34+
Array(a)
35+
Maybe(a)
36+
String
37+
Number
38+
Object
39+
Time
40+
Bool
41+
MINT
42+
)
43+
44+
snippet "The decode:", node
45+
end unless check_decode(type)
46+
47+
result_type =
48+
Type.new("Result", [OBJECT_ERROR, type] of Checkable)
49+
50+
if item = node.expression
51+
expression =
52+
resolve item
53+
54+
error! :decode_expected_object do
55+
block do
56+
text "Only the"
57+
bold %("Object")
58+
text "type:"
59+
end
60+
61+
snippet expression
62+
snippet "The decoded question:", node
63+
end unless Comparer.compare(expression, OBJECT)
64+
65+
result_type
66+
else
67+
Type.new("Function", [OBJECT, result_type] of Checkable)
68+
end
69+
end
70+
71+
def check_decode(type : Checkable)
72+
case type
73+
when Record
74+
type.fields.all? do |_, value|
75+
check_decode value
76+
end
77+
when Variable
78+
false
79+
else
80+
case type.name
81+
when "String", "Time", "Number", "Bool", "Object"
82+
true
83+
when "Map"
84+
type.parameters.first.name == "String" &&
85+
type.parameters.first.parameters.size == 0 &&
86+
check_decode(type.parameters.last)
87+
when "Tuple"
88+
type.parameters.all? { |item| check_decode(item) }
89+
when "Array", "Maybe"
90+
if type.parameters.size == 1
91+
check_decode type.parameters.first
92+
else
93+
false
94+
end
95+
else
96+
false
97+
end
98+
end
99+
end
100+
end
101+
end

0 commit comments

Comments
 (0)