Passed
Push — master ( d3af4b...8569a9 )
by Alec
01:51
created

Circular   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 131
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 36
dl 0
loc 131
ccs 45
cts 45
cp 1
rs 10
c 0
b 0
f 0
wmc 19

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __invoke() 0 3 1
A convert() 0 18 4
A refineData() 0 11 4
A value() 0 11 3
A __construct() 0 3 1
A setOneElement() 0 4 1
A rewind() 0 3 1
A current() 0 3 1
A valid() 0 4 1
A next() 0 3 1
A key() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AlecRabbit\Accessories;
6
7
use function AlecRabbit\typeOf;
8
9
/**
10
 * Class Circular
11
 */
12
class Circular implements \Iterator
13
{
14
    /** @var Rewindable */
15
    protected $data;
16
17
    /** @var bool */
18
    protected $oneElement = false;
19
20
    /**
21
     * Circular constructor.
22
     * @param array|callable|Rewindable $data accepts array, callable which returns \Generator or Rewindable
23
     */
24 11
    public function __construct($data)
25
    {
26 11
        $this->data = $this->refineData($data);
27 9
    }
28
29
    /**
30
     * @param mixed $data
31
     * @return mixed
32
     */
33 11
    protected function refineData($data)
34
    {
35 11
        if (\is_array($data)) {
36 7
            if (1 === $count = count($data)) {
37 2
                return $this->setOneElement(reset($data));
38
            }
39 5
            if (0 === $count) {
40 1
                return $this->setOneElement();
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->setOneElement() targeting AlecRabbit\Accessories\Circular::setOneElement() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
41
            }
42
        }
43 8
        return $this->convert($data);
44
    }
45
46
    /**
47
     * @param mixed $data
48
     * @return mixed
49
     */
50 3
    protected function setOneElement($data = null)
51
    {
52 3
        $this->oneElement = true;
53 3
        return $data;
54
    }
55
56
    /**
57
     * @param mixed $arg
58
     * @return Rewindable
59
     */
60 8
    private function convert(&$arg): Rewindable
61
    {
62 8
        if (\is_array($arg)) {
63
            return
64 4
                new Rewindable(
65
                    static function () use (&$arg): \Generator {
66 4
                        yield from $arg;
67 4
                    }
68
                );
69
        }
70 4
        if (\is_callable($arg)) {
71
            return
72 2
                new Rewindable($arg);
73
        }
74 2
        if ($arg instanceof Rewindable) {
75 1
            return $arg;
76
        }
77 1
        throw new \InvalidArgumentException('Unexpected argument type: ' . typeOf($arg) . ' for ' . Caller::get());
78
    }
79
80
    /**
81
     * @return mixed
82
     */
83 2
    public function __invoke()
84
    {
85 2
        return $this->value();
86
    }
87
88
    /**
89
     * @return mixed
90
     */
91 5
    public function value()
92
    {
93 5
        if ($this->oneElement) {
94 3
            return $this->data;
95
        }
96 2
        if (null === $value = $this->current()) {
97 2
            $this->rewind();
98 2
            $value = $this->current();
99
        }
100 2
        $this->next();
101 2
        return $value;
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107 6
    public function current()
108
    {
109 6
        return $this->data->current();
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115 6
    public function rewind(): void
116
    {
117 6
        $this->data->rewind();
118 6
    }
119
120
    /**
121
     * {@inheritdoc}
122
     */
123 6
    public function next(): void
124
    {
125 6
        $this->data->next();
126 6
    }
127
128
    /**
129
     * {@inheritdoc}
130
     */
131 4
    public function valid(): bool
132
    {
133
        return
134 4
            $this->data->valid();
135
    }
136
137
    /**
138
     * {@inheritdoc}
139
     */
140 4
    public function key()
141
    {
142 4
        return $this->data->key();
143
    }
144
}
145