@@ -113,6 +113,66 @@ module Onyx::SQL::Model
113113 {% end % }
114114 end
115115 end
116+
117+ {% verbatim do % }
118+ # Initialize an instance of `self`. It accepts an arbitrary amount of arguments,
119+ # but they must match the variable names, raising in compile-time instead:
120+ #
121+ # ```
122+ # User.new(id: 42, username: "John") # => <User @id=42 @username="John">
123+ # User.new(foo: "bar") # Compilation-time error
124+ # ```
125+ def initialize (** values : ** T ) : self forall T
126+ {% for ivar in @type .instance_vars % }
127+ {%
128+ a = 42 # BUG: Dummy assignment, otherwise the compiler crashes
129+
130+ unless ivar.type.nilable?
131+ raise " #{ @type } @#{ ivar.name } must be nilable, as it's an Onyx::SQL::Model variable"
132+ end
133+
134+ unless ivar.type.union_types.size == 2
135+ raise " Only T | Nil unions can be an Onyx::SQL::Model's variables (got #{ ivar.type } type for #{ @type } @#{ ivar.name } )"
136+ end
137+
138+ type = ivar.type.union_types.find { |t | t != Nil }
139+
140+ if type <= Enumerable
141+ if (type .type_vars.size != 1 || type .type_vars.first.union?)
142+ raise " If an Onyx::SQL::Model variable is a Enumerable, it must have a single non-union type var (got #{ type } type for #{ @type } @#{ ivar.name } )"
143+ end
144+ end
145+ % }
146+ {% end % }
147+
148+ values.each do |key , value |
149+ {% begin % }
150+ case key
151+ {% for key, value in T % }
152+ {% found = false % }
153+
154+ {% for ivar in @type .instance_vars % }
155+ {% if ivar.name == key % }
156+ {% raise " Invalid type #{ value } for #{ @type } @#{ ivar.name } (expected #{ ivar.type } )" unless value <= ivar.type % }
157+
158+ when {{ivar.name.symbolize}}
159+ @{{ivar.name}} = value.as({{value}})
160+
161+ {% found = true % }
162+ {% end % }
163+ {% end % }
164+
165+ {% raise " Cannot find instance variable by key #{ key } in #{ @type } " unless found % }
166+ {% end % }
167+ else
168+ raise " BUG: Runtime key mismatch"
169+ end
170+ {% end % }
171+ end
172+
173+ self
174+ end
175+ {% end % }
116176 end
117177
118178 # Compare `self` against *other* model of the same type by their primary keys.
@@ -136,64 +196,6 @@ module Onyx::SQL::Model
136196 {% end % }
137197 end
138198
139- # Initialize an instance of `self`. It accepts an arbitrary amount of arguments,
140- # but they must match the variable names, raising in compile-time instead:
141- #
142- # ```
143- # User.new(id: 42, username: "John") # => <User @id=42 @username="John">
144- # User.new(foo: "bar") # Compilation-time error
145- # ```
146- def initialize (** values : ** T ) : self forall T
147- {% for ivar in @type .instance_vars % }
148- {%
149- a = 42 # BUG: Dummy assignment, otherwise the compiler crashes
150-
151- unless ivar.type.nilable?
152- raise " #{ @type } @#{ ivar.name } must be nilable, as it's an Onyx::SQL::Model variable"
153- end
154-
155- unless ivar.type.union_types.size == 2
156- raise " Only T | Nil unions can be an Onyx::SQL::Model's variables (got #{ ivar.type } type for #{ @type } @#{ ivar.name } )"
157- end
158-
159- type = ivar.type.union_types.find { |t | t != Nil }
160-
161- if type <= Enumerable
162- if (type .type_vars.size != 1 || type .type_vars.first.union?)
163- raise " If an Onyx::SQL::Model variable is a Enumerable, it must have a single non-union type var (got #{ type } type for #{ @type } @#{ ivar.name } )"
164- end
165- end
166- % }
167- {% end % }
168-
169- values.each do |key , value |
170- {% begin % }
171- case key
172- {% for key, value in T % }
173- {% found = false % }
174-
175- {% for ivar in @type .instance_vars % }
176- {% if ivar.name == key % }
177- {% raise " Invalid type #{ value } for #{ @type } @#{ ivar.name } (expected #{ ivar.type } )" unless value <= ivar.type % }
178-
179- when {{ivar.name.symbolize}}
180- @{{ivar.name}} = value.as({{value}})
181-
182- {% found = true % }
183- {% end % }
184- {% end % }
185-
186- {% raise " Cannot find instance variable by key #{ key } in #{ @type } " unless found % }
187- {% end % }
188- else
189- raise " BUG: Runtime key mismatch"
190- end
191- {% end % }
192- end
193-
194- self
195- end
196-
197199 # This annotation specifies options for a `Model`. It has two mandatory options itself:
198200 #
199201 # * `:table` -- the table name in the DB, e.g. "users"
0 commit comments