55
66use Closure ;
77use DOMElement ;
8- use Generator ;
98use Soap \Encoding \Encoder \Context ;
109use Soap \Encoding \Encoder \Feature \ListAware ;
11- use Soap \Encoding \Encoder \SimpleType \ScalarTypeEncoder ;
1210use Soap \Encoding \Encoder \XmlEncoder ;
1311use Soap \Encoding \TypeInference \XsiTypeDetector ;
1412use Soap \Encoding \Xml \Node \Element ;
15- use Soap \Encoding \Xml \Reader \ElementValueReader ;
1613use Soap \Encoding \Xml \Writer \XsdTypeXmlElementWriter ;
1714use Soap \Encoding \Xml \Writer \XsiAttributeBuilder ;
18- use Soap \Engine \Metadata \Model \XsdType ;
1915use Soap \WsdlReader \Model \Definitions \BindingUse ;
20- use Soap \WsdlReader \Parser \Xml \QnameParser ;
2116use VeeWee \Reflecta \Iso \Iso ;
22- use XMLWriter ;
2317use function count ;
18+ use function Psl \Fun \lazy ;
2419use function Psl \Vec \map ;
2520use function VeeWee \Xml \Dom \Locator \Element \children as readChildren ;
2621use function VeeWee \Xml \Writer \Builder \children ;
27- use function VeeWee \Xml \Writer \Builder \element ;
28- use function VeeWee \Xml \Writer \Builder \namespaced_element ;
2922use function VeeWee \Xml \Writer \Builder \prefixed_attribute ;
30- use function VeeWee \Xml \Writer \Builder \value as buildValue ;
23+ use function VeeWee \Xml \Writer \Builder \raw as buildRaw ;
3124
3225/**
3326 * @implements XmlEncoder<list<mixed>, non-empty-string>
@@ -39,39 +32,35 @@ final class SoapArrayEncoder implements ListAware, XmlEncoder
3932 */
4033 public function iso (Context $ context ): Iso
4134 {
35+ $ arrayAccess = lazy (static fn (): SoapArrayAccess => SoapArrayAccess::forContext ($ context ));
36+
4237 return (new Iso (
4338 /**
4439 * @param list<mixed> $value
4540 * @return non-empty-string
4641 */
47- fn (array $ value ): string => $ this ->encodeArray ($ context , $ value ),
42+ fn (array $ value ): string => $ this ->encodeArray ($ context , $ arrayAccess (), $ value ),
4843 /**
4944 * @param non-empty-string|Element $value
5045 * @return list<mixed>
5146 */
5247 fn (string |Element $ value ): array => $ this ->decodeArray (
5348 $ context ,
49+ $ arrayAccess (),
5450 $ value instanceof Element ? $ value : Element::fromString ($ value )
5551 ),
5652 ));
5753 }
5854
55+
5956 /**
6057 * @param list<mixed> $data
6158 *
6259 * @return non-empty-string
6360 */
64- private function encodeArray (Context $ context , array $ data ): string
61+ private function encodeArray (Context $ context , SoapArrayAccess $ arrayAccess , array $ data ): string
6562 {
66- $ type = $ context ->type ;
67- $ meta = $ type ->getMeta ();
68- $ itemNodeName = $ meta ->arrayNodeName ()->unwrapOr (null );
69- $ itemType = $ meta ->arrayType ()
70- ->map (static fn (array $ info ): string => $ info ['itemType ' ])
71- ->unwrapOr (XsiTypeDetector::detectFromValue (
72- $ context ->withType (XsdType::any ()),
73- $ data [0 ] ?? null
74- ));
63+ $ iso = $ arrayAccess ->itemEncoder ->iso ($ arrayAccess ->itemContext );
7564
7665 return (new XsdTypeXmlElementWriter ())(
7766 $ context ,
@@ -86,66 +75,35 @@ private function encodeArray(Context $context, array $data): string
8675 prefixed_attribute (
8776 'SOAP-ENC ' ,
8877 'arrayType ' ,
89- $ itemType . '[ ' .count ($ data ).'] '
78+ $ arrayAccess -> xsiType . '[ ' .count ($ data ).'] '
9079 ),
9180 ]
9281 : []
9382 ),
9483 ...map (
9584 $ data ,
96- fn (mixed $ value ): Closure => $ this -> itemElement ( $ context , $ itemNodeName , $ itemType , $ value )
85+ static fn (mixed $ value ): Closure => buildRaw (( string ) $ iso -> to ( $ value) )
9786 )
9887 ])
9988 );
10089 }
10190
102- /**
103- * @psalm-param mixed $value
104- * @return Closure(XMLWriter): Generator<bool>
105- */
106- private function itemElement (Context $ context , ?string $ itemNodeName , string $ itemType , mixed $ value ): Closure
107- {
108- $ buildValue = buildValue (ScalarTypeEncoder::default ()->iso ($ context )->to ($ value ));
109-
110- if ($ context ->bindingUse === BindingUse::ENCODED || $ itemNodeName !== null ) {
111- return element (
112- $ itemNodeName ?? 'item ' ,
113- children ([
114- (new XsiAttributeBuilder ($ context , $ itemType )),
115- $ buildValue
116- ])
117- );
118- }
119-
120- [$ prefix , $ localName ] = (new QnameParser ())($ itemType );
121-
122- return namespaced_element (
123- $ context ->namespaces ->lookupNamespaceFromName ($ prefix )->unwrap (),
124- $ prefix ,
125- $ localName ,
126- $ buildValue
127- );
128- }
129-
13091 /**
13192 * @return list<mixed>
13293 */
133- private function decodeArray (Context $ context , Element $ value ): array
94+ private function decodeArray (Context $ context , SoapArrayAccess $ arrayAccess , Element $ value ): array
13495 {
13596 $ element = $ value ->element ();
97+ $ iso = $ arrayAccess ->itemEncoder ->iso ($ arrayAccess ->itemContext );
13698
13799 return readChildren ($ element )->reduce (
138100 /**
139101 * @param list<mixed> $list
140102 * @return list<mixed>
141103 */
142- static function (array $ list , DOMElement $ item ) use ($ context ): array {
143- /** @psalm-var mixed $value */
144- $ value = (new ElementValueReader ())(
145- $ context ->withType (XsdType::any ()),
146- ScalarTypeEncoder::default (),
147- $ item
148- );
104+ static function (array $ list , DOMElement $ item ) use ($ iso ): array {
105+ /** @var mixed $value */
106+ $ value = $ iso ->from (Element::fromDOMElement ($ item ));
149107
150108 return [...$ list , $ value ];
151109 },
0 commit comments