1<?php
2
3namespace DeepCopy\TypeFilter\Spl;
4
5use Closure;
6use DeepCopy\DeepCopy;
7use DeepCopy\TypeFilter\TypeFilter;
8use SplDoublyLinkedList;
9
10/**
11 * @final
12 */
13class SplDoublyLinkedListFilter implements TypeFilter
14{
15    private $copier;
16
17    public function __construct(DeepCopy $copier)
18    {
19        $this->copier = $copier;
20    }
21
22    /**
23     * {@inheritdoc}
24     */
25    public function apply($element)
26    {
27        $newElement = clone $element;
28
29        $copy = $this->createCopyClosure();
30
31        return $copy($newElement);
32    }
33
34    private function createCopyClosure()
35    {
36        $copier = $this->copier;
37
38        $copy = function (SplDoublyLinkedList $list) use ($copier) {
39            // Replace each element in the list with a deep copy of itself
40            for ($i = 1; $i <= $list->count(); $i++) {
41                $copy = $copier->recursiveCopy($list->shift());
42
43                $list->push($copy);
44            }
45
46            return $list;
47        };
48
49        return Closure::bind($copy, null, DeepCopy::class);
50    }
51}
52