RewindableGenerator::valid()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare( strict_types = 1 );
4
5
/**
6
 * @licence GNU GPL v2+
7
 * @author Jeroen De Dauw < [email protected] >
8
 */
9
class RewindableGenerator implements Iterator {
10
11
	/**
12
	 * @var callable
13
	 */
14
	private $generatorFunction;
15
16
	/**
17
	 * @var Generator
18
	 */
19
	private $generator;
20
21
	/**
22
	 * @var callable|null
23
	 */
24
	private $onRewind;
25
26
	/**
27
	 * @param callable $generatorConstructionFunction A callable that should return a Generator
28
	 * @param callable $onRewind callable that gets invoked with 0 arguments after the iterator was rewinded
29
	 *
30
	 * @throws InvalidArgumentException
31
	 */
32 9
	public function __construct( callable $generatorConstructionFunction, callable $onRewind = null ) {
33 9
		$this->generatorFunction = $generatorConstructionFunction;
34 9
		$this->onRewind = $onRewind;
35 9
		$this->generateGenerator();
36 8
	}
37
38 9
	private function generateGenerator() {
39 9
		$this->generator = call_user_func( $this->generatorFunction );
40
41 9
		if ( !( $this->generator instanceof Generator ) ) {
42 1
			throw new InvalidArgumentException( 'The callable needs to return a Generator' );
43
		}
44 8
	}
45
46
	/**
47
	 * Return the current element
48
	 * @see Iterator::current
49
	 * @link http://php.net/manual/en/iterator.current.php
50
	 * @return mixed
51
	 */
52 4
	public function current() {
53 4
		return $this->generator->current();
54
	}
55
56
	/**
57
	 * Move forward to next element
58
	 * @see Iterator::next
59
	 * @link http://php.net/manual/en/iterator.next.php
60
	 */
61 4
	public function next() {
62 4
		$this->generator->next();
63 4
	}
64
65
	/**
66
	 * Return the key of the current element
67
	 * @see Iterator::key
68
	 * @link http://php.net/manual/en/iterator.key.php
69
	 * @return mixed scalar on success, or null on failure.
70
	 */
71 3
	public function key() {
72 3
		return $this->generator->key();
73
	}
74
75
	/**
76
	 * Checks if current position is valid
77
	 * @see Iterator::rewind
78
	 * @link http://php.net/manual/en/iterator.valid.php
79
	 * @return boolean
80
	 */
81 4
	public function valid() {
82 4
		return $this->generator->valid();
83
	}
84
85
	/**
86
	 * Rewind the Iterator to the first element
87
	 * @see Iterator::rewind
88
	 * @link http://php.net/manual/en/iterator.rewind.php
89
	 */
90 6
	public function rewind() {
91 6
		$this->generateGenerator();
92
93 6
		if ( is_callable( $this->onRewind ) ) {
94 2
			call_user_func( $this->onRewind );
95
		}
96
97 6
		if ( defined( 'HHVM_VERSION' ) ) {
98
			$this->generator->next();
99
		}
100 6
	}
101
102
	/**
103
	 * Sets a callable that gets invoked with 0 arguments after the iterator was rewinded.
104
	 * If a callable has been set already, an exception will be thrown.
105
	 *
106
	 * @since 1.1.0
107
	 *
108
	 * @param callable $onRewind
109
	 * @throws InvalidArgumentException
110
	 */
111 2
	public function onRewind( callable $onRewind ) {
112 2
		if ( $this->onRewind !== null ) {
113 2
			throw new InvalidArgumentException( 'Can only bind a onRewind handler once' );
114
		}
115
116 1
		$this->onRewind = $onRewind;
117 1
	}
118
119
}
120
121