1<?php 2 3declare(strict_types=1); 4 5namespace JMS\Serializer\Handler; 6 7use JMS\Serializer\DeserializationContext; 8use JMS\Serializer\GraphNavigatorInterface; 9use JMS\Serializer\SerializationContext; 10use JMS\Serializer\Visitor\DeserializationVisitorInterface; 11use JMS\Serializer\Visitor\SerializationVisitorInterface; 12 13final class IteratorHandler implements SubscribingHandlerInterface 14{ 15 private const SUPPORTED_FORMATS = ['json', 'xml']; 16 17 /** 18 * {@inheritdoc} 19 */ 20 public static function getSubscribingMethods() 21 { 22 $methods = []; 23 24 foreach (self::SUPPORTED_FORMATS as $format) { 25 $methods[] = [ 26 'direction' => GraphNavigatorInterface::DIRECTION_SERIALIZATION, 27 'type' => \ArrayIterator::class, 28 'format' => $format, 29 'method' => 'serializeIterator', 30 ]; 31 32 $methods[] = [ 33 'direction' => GraphNavigatorInterface::DIRECTION_DESERIALIZATION, 34 'type' => \ArrayIterator::class, 35 'format' => $format, 36 'method' => 'deserializeIterator', 37 ]; 38 } 39 40 foreach (self::SUPPORTED_FORMATS as $format) { 41 $methods[] = [ 42 'direction' => GraphNavigatorInterface::DIRECTION_SERIALIZATION, 43 'type' => \Generator::class, 44 'format' => $format, 45 'method' => 'serializeIterator', 46 ]; 47 48 $methods[] = [ 49 'direction' => GraphNavigatorInterface::DIRECTION_DESERIALIZATION, 50 'type' => \Generator::class, 51 'format' => $format, 52 'method' => 'deserializeGenerator', 53 ]; 54 } 55 56 return $methods; 57 } 58 59 /** 60 * @return mixed[]|\ArrayObject 61 */ 62 public function serializeIterator( 63 SerializationVisitorInterface $visitor, 64 \Iterator $iterator, 65 array $type, 66 SerializationContext $context 67 ) { 68 $type['name'] = 'array'; 69 70 $context->stopVisiting($iterator); 71 $result = $visitor->visitArray(iterator_to_array($iterator), $type); 72 $context->startVisiting($iterator); 73 74 return $result; 75 } 76 77 /** 78 * @param mixed $data 79 */ 80 public function deserializeIterator( 81 DeserializationVisitorInterface $visitor, 82 $data, 83 array $type, 84 DeserializationContext $context 85 ): \Iterator { 86 $type['name'] = 'array'; 87 88 return new \ArrayIterator($visitor->visitArray($data, $type)); 89 } 90 91 92 /** 93 * @param mixed $data 94 */ 95 public function deserializeGenerator( 96 DeserializationVisitorInterface $visitor, 97 $data, 98 array $type, 99 DeserializationContext $context 100 ): \Generator { 101 return (static function () use (&$visitor, &$data, &$type): \Generator { 102 $type['name'] = 'array'; 103 foreach ($visitor->visitArray($data, $type) as $key => $item) { 104 yield $key => $item; 105 } 106 })(); 107 } 108} 109