PipeSelector   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 65
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 7
eloc 13
c 1
b 0
f 1
dl 0
loc 65
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getValue() 0 3 1
A compatibleWith() 0 9 3
A select() 0 8 2
A __construct() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Smoren\ArrayView\Selectors;
6
7
use Smoren\ArrayView\Interfaces\ArraySelectorInterface;
8
use Smoren\ArrayView\Interfaces\ArrayViewInterface;
9
use Smoren\ArrayView\Interfaces\PipeSelectorInterface;
10
use Smoren\ArrayView\Views\ArrayView;
11
12
/**
13
 * Represents a selector that applies a series of selectors sequentially to a source array view.
14
 *
15
 * ```php
16
 * $originalArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
17
 * $selector = new PipeSelector([
18
 *     new SliceSelector('::2'),
19
 *     new MaskSelector([true, false, true, true, true]),
20
 *     new IndexListSelector([0, 1, 2]),
21
 *     new SliceSelector('1:'),
22
 * ]);
23
 *
24
 * $view = ArrayView::toView($originalArray);
25
 * $subview = $view->subview($selector);
26
 * print_r($subview[':']); // [5, 7]
27
 *
28
 * $subview[':'] = [55, 77];
29
 * print_r($originalArray); // [1, 2, 3, 4, 55, 6, 77, 8, 9, 10]
30
 * ```
31
 *
32
 * ##### Example with nested pipes
33
 * ```php
34
 * $originalArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
35
 * $selector = new PipeSelector([
36
 *     new SliceSelector('::2'),
37
 *     new PipeSelector([
38
 *         new MaskSelector([true, false, true, true, true]),
39
 *         new IndexListSelector([0, 1, 2]),
40
 *     ])
41
 *     new SliceSelector('1:'),
42
 * ]);
43
 *
44
 * $view = ArrayView::toView($originalArray);
45
 * $subview = $view->subview($selector);
46
 * print_r($subview[':']); // [5, 7]
47
 *
48
 * $subview[':'] = [55, 77];
49
 * print_r($originalArray); // [1, 2, 3, 4, 55, 6, 77, 8, 9, 10]
50
 * ```
51
 */
52
final class PipeSelector implements PipeSelectorInterface
53
{
54
    /**
55
     * @var array<ArraySelectorInterface> An array of selectors to be applied sequentially.
56
     */
57
    private array $selectors;
58
59
    /**
60
     * Creates a new PipeSelector instance with the provided selectors array.
61
     *
62
     * @param array<ArraySelectorInterface> $selectors An array of selectors to be assigned to the PipeSelector.
63
     */
64
    public function __construct(array $selectors)
65
    {
66
        $this->selectors = $selectors;
67
    }
68
69
    /**
70
     * Applies the series of selectors to the given source array view.
71
     *
72
     * @template T The type of elements in the source array view.
73
     *
74
     * @param ArrayViewInterface<T> $source The source array view to select from.
75
     * @param bool|null $readonly Optional parameter to specify if the view should be read-only.
76
     *
77
     * @return ArrayViewInterface<T> The resulting array view after applying all selectors.
78
     */
79
    public function select(ArrayViewInterface $source, ?bool $readonly = null): ArrayViewInterface
80
    {
81
        $view = ArrayView::toView($source, $readonly);
82
        foreach ($this->selectors as $selector) {
83
            $view = $selector->select($view, $readonly);
84
        }
85
        /** @var ArrayViewInterface<T> $view  */
86
        return $view;
87
    }
88
89
    /**
90
     * Checks if the series of selectors are compatible with the given array view.
91
     *
92
     * @template T The type of elements in the source array view.
93
     *
94
     * @param ArrayViewInterface<T> $view The array view to check compatibility with.
95
     *
96
     * @return bool True if all selectors are compatible with the array view, false otherwise.
97
     */
98
    public function compatibleWith(ArrayViewInterface $view): bool
99
    {
100
        foreach ($this->selectors as $selector) {
101
            if (!$selector->compatibleWith($view)) {
102
                return false;
103
            }
104
            $view = $selector->select($view);
105
        }
106
        return true;
107
    }
108
109
    /**
110
     * Returns the array of selectors assigned to the PipeSelector.
111
     *
112
     * @return array<ArraySelectorInterface> The array of selectors.
113
     */
114
    public function getValue(): array
115
    {
116
        return $this->selectors;
117
    }
118
}
119