@@ -39,32 +39,37 @@ struct NamedTupleConstructor{names} end
3939 end
4040end
4141
42- function assert_hasfields (T, fnames)
43- for fname in fnames
44- if ! (fname in fieldnames (T))
45- msg = " $T has no field $fname "
46- throw (ArgumentError (msg))
47- end
48- end
49- end
50-
5142function setproperties (obj; kw... )
5243 setproperties (obj, (;kw... ))
5344end
5445
5546@generated function setproperties (obj, patch:: NamedTuple )
56- assert_hasfields (obj, fieldnames (patch))
57- args = map (fieldnames (obj)) do fn
58- if fn in fieldnames (patch)
59- :(patch.$ fn)
60- else
61- :(obj.$ fn)
47+ if issubset (fieldnames (patch), fieldnames (obj))
48+ args = map (fieldnames (obj)) do fn
49+ if fn in fieldnames (patch)
50+ :(patch.$ fn)
51+ else
52+ :(obj.$ fn)
53+ end
6254 end
55+ return Expr (:block ,
56+ Expr (:meta , :inline ),
57+ Expr (:call ,:(constructorof ($ obj)), args... )
58+ )
59+ else
60+ :(setproperties_unknown_field_error (obj, patch))
6361 end
64- Expr (:block ,
65- Expr (:meta , :inline ),
66- Expr (:call ,:(constructorof ($ obj)), args... )
67- )
62+ end
63+
64+ function setproperties_unknown_field_error (obj, patch)
65+ O = typeof (obj)
66+ P = typeof (patch)
67+ msg = """
68+ Failed to assign properties $(fieldnames (P)) to object with fields $(fieldnames (O)) .
69+ You may want to overload
70+ ConstructionBase.setproperties(obj::$O , patch::NamedTuple)
71+ """
72+ throw (ArgumentError (msg))
6873end
6974
7075
0 commit comments