44namespace Soap \Encoding \Encoder ;
55
66use Closure ;
7+ use Exception ;
78use Soap \Encoding \Normalizer \PhpPropertyNameNormalizer ;
89use Soap \Encoding \TypeInference \ComplexTypeBuilder ;
910use Soap \Encoding \TypeInference \XsiTypeDetector ;
1314use Soap \Encoding \Xml \Writer \XsdTypeXmlElementWriter ;
1415use Soap \Encoding \Xml \Writer \XsiAttributeBuilder ;
1516use Soap \Engine \Metadata \Model \Property ;
16- use Soap \Engine \Metadata \Model \XsdType ;
17+ use Soap \Engine \Metadata \Model \TypeMeta ;
1718use VeeWee \Reflecta \Iso \Iso ;
1819use VeeWee \Reflecta \Lens \Lens ;
1920use function is_array ;
@@ -100,30 +101,27 @@ private function to(Context $context, array $properties, object|array $data): st
100101 $ properties ,
101102 function (Property $ property ) use ($ context , $ data , $ defaultAction ) : Closure {
102103 $ type = $ property ->getType ();
103- $ lens = $ this ->decorateLensForType (
104+ $ meta = $ type ->getMeta ();
105+ $ isAttribute = $ meta ->isAttribute ()->unwrapOr (false );
106+
107+ /** @var mixed $value */
108+ $ value = $ this ->runLens (
104109 property (PhpPropertyNameNormalizer::normalize ($ property ->getName ())),
105- $ type
110+ $ meta ,
111+ $ data ,
112+ null
106113 );
107- /**
108- * @psalm-var mixed $value
109- * @psalm-suppress PossiblyInvalidArgument - Psalm gets lost in the lens.
110- */
111- $ value = $ lens
112- ->tryGet ($ data )
113- ->catch (static fn () => null )
114- ->getResult ();
115-
116- return $ this ->handleProperty (
117- $ property ,
118- onAttribute: fn (): Closure => $ value ? (new AttributeBuilder (
114+
115+ return match (true ) {
116+ $ isAttribute => $ value ? (new AttributeBuilder (
119117 $ type ,
120118 $ this ->grabIsoForProperty ($ context , $ property )->to ($ value )
121119 ))(...) : $ defaultAction ,
122- onValue: fn (): Closure => $ value
120+ $ property -> getName () === ' _ ' => $ value
123121 ? buildValue ($ this ->grabIsoForProperty ($ context , $ property )->to ($ value ))
124122 : (new NilAttributeBuilder ())(...),
125- onElements: fn (): Closure => $ value ? raw ($ this ->grabIsoForProperty ($ context , $ property )->to ($ value )) : $ defaultAction,
126- ) ;
123+ default => $ value ? raw ($ this ->grabIsoForProperty ($ context , $ property )->to ($ value )) : $ defaultAction
124+ } ;
127125 }
128126 )
129127 ]
@@ -149,23 +147,21 @@ private function from(Context $context, array $properties, string $data): object
149147 function (Property $ property ) use ($ context , $ nodes ): mixed {
150148 $ type = $ property ->getType ();
151149 $ meta = $ type ->getMeta ();
152- $ isList = $ meta -> isList ()-> unwrapOr ( false );
153- /** @psalm- var string|null $value */
154- $ value = $ this ->decorateLensForType (
150+
151+ /** @var string|null $value */
152+ $ value = $ this ->runLens (
155153 index ($ property ->getName ()),
156- $ type
157- )
158- ->tryGet ($ nodes )
159- ->catch (static fn () => null )
160- ->getResult ();
161- $ defaultValue = $ isList ? [] : null ;
162-
163- return $ this ->handleProperty (
164- $ property ,
165- onAttribute: fn (): mixed => /** @psalm-suppress PossiblyNullArgument */ $ this ->grabIsoForProperty ($ context , $ property )->from ($ value ),
166- onValue: fn (): mixed => $ value !== null ? $ this ->grabIsoForProperty ($ context , $ property )->from ($ value ) : $ defaultValue ,
167- onElements: fn (): mixed => $ value !== null ? $ this ->grabIsoForProperty ($ context , $ property )->from ($ value ) : $ defaultValue ,
154+ $ meta ,
155+ $ nodes ,
156+ null
168157 );
158+ $ defaultValue = $ meta ->isList ()->unwrapOr (false ) ? [] : null ;
159+
160+ /** @psalm-suppress PossiblyNullArgument */
161+ return match (true ) {
162+ $ meta ->isAttribute ()->unwrapOr (false ) => $ this ->grabIsoForProperty ($ context , $ property )->from ($ value ),
163+ default => $ value !== null ? $ this ->grabIsoForProperty ($ context , $ property )->from ($ value ) : $ defaultValue ,
164+ };
169165 },
170166 static fn (Property $ property ) => PhpPropertyNameNormalizer::normalize ($ property ->getName ()),
171167 )
@@ -183,27 +179,14 @@ private function grabIsoForProperty(Context $context, Property $property): Iso
183179 return $ encoder ->iso ($ propertyContext );
184180 }
185181
186- /**
187- * @template X
188- *
189- * @param Closure(): X $onAttribute
190- * @param Closure(): X $onValue
191- * @param Closure(): X $onElements
192- * @return X
193- */
194- private function handleProperty (
195- Property $ property ,
196- Closure $ onAttribute ,
197- Closure $ onValue ,
198- Closure $ onElements ,
199- ) {
200- $ meta = $ property ->getType ()->getMeta ();
201-
202- return match (true ) {
203- $ meta ->isAttribute ()->unwrapOr (false ) => $ onAttribute (),
204- $ property ->getName () === '_ ' => $ onValue (),
205- default => $ onElements ()
206- };
182+ private function runLens (Lens $ lens , TypeMeta $ meta , mixed $ data , mixed $ default ): mixed
183+ {
184+ try {
185+ /** @var mixed */
186+ return $ this ->decorateLensForType ($ lens , $ meta )->get ($ data );
187+ } catch (Exception $ e ) {
188+ return $ default ;
189+ }
207190 }
208191
209192 /**
@@ -214,9 +197,8 @@ private function handleProperty(
214197 *
215198 * @return Lens<S, A>
216199 */
217- private function decorateLensForType (Lens $ lens , XsdType $ type ): Lens
200+ private function decorateLensForType (Lens $ lens , TypeMeta $ meta ): Lens
218201 {
219- $ meta = $ type ->getMeta ();
220202 if ($ meta ->isNullable ()->unwrapOr (false )) {
221203 return optional ($ lens );
222204 }
@@ -237,14 +219,13 @@ private function decorateLensForType(Lens $lens, XsdType $type): Lens
237219 private function detectProperties (Context $ context ): array
238220 {
239221 $ type = (new ComplexTypeBuilder ())($ context );
240- $ properties = reindex (
222+
223+ return reindex (
241224 sort_by (
242225 $ type ->getProperties (),
243226 static fn (Property $ property ): bool => !$ property ->getType ()->getMeta ()->isAttribute ()->unwrapOr (false ),
244227 ),
245228 static fn (Property $ property ): string => $ property ->getName (),
246229 );
247-
248- return $ properties ;
249230 }
250231}
0 commit comments