Completed
Push — master ( 3988cf...54e09a )
by James
11s
created
src/Contract/Axolotl/Dictionary.php 1 patch
Indentation   +174 added lines, -174 removed lines patch added patch discarded remove patch
@@ -5,178 +5,178 @@
 block discarded – undo
5 5
 use Iterator;
6 6
 
7 7
 interface Dictionary extends Iterator, Countable, Serializes {
8
-	/**
9
-	 * Returns the type of the dictionary's keys.
10
-	 *
11
-	 * @return string
12
-	 */
13
-	public function get_key_type();
14
-
15
-	/**
16
-	 * Returns the type of the dictionary's values.
17
-	 *
18
-	 * @return string
19
-	 */
20
-	public function get_value_type();
21
-
22
-	/**
23
-	 * Returns true if $key is in the dictionary, returns false if it is not.
24
-	 *
25
-	 * @param mixed $key Key to check for.
26
-	 *
27
-	 * @return bool
28
-	 */
29
-	public function exists( $key );
30
-
31
-	/**
32
-	 * Returns true if the callable returns true. The callable should accept a
33
-	 * key and value as arguments and return a boolean.
34
-	 *
35
-	 * @param  callable $callable
36
-	 * @return bool
37
-	 */
38
-	public function contains( $callable );
39
-
40
-	/**
41
-	 * Returns the value associated with $key.
42
-	 *
43
-	 * @param mixed $key Key to get.
44
-	 *
45
-	 * @return mixed
46
-	 */
47
-	public function get( $key );
48
-
49
-	/**
50
-	 * Removes the key-value pair represented by $key from the dictionary.
51
-	 *
52
-	 * @param mixed $key Key to remove.
53
-	 *
54
-	 * @return static
55
-	 */
56
-	public function delete( $key );
57
-
58
-	/**
59
-	 * Returns true if $value is in the dictionary, returns false if not.
60
-	 *
61
-	 * @param mixed $value Value to check for existence.
62
-	 *
63
-	 * @return bool
64
-	 */
65
-	public function value_exists( $value );
66
-
67
-	/**
68
-	 * Returns the number of key-value pairs in the dictionary.
69
-	 *
70
-	 * @return int
71
-	 */
72
-	public function count();
73
-
74
-	/**
75
-	 * Removes every key-value pair from the dictionary.
76
-	 *
77
-	 * @return static
78
-	 */
79
-	public function clear();
80
-
81
-	/**
82
-	 * Returns the key-value pairs in the dictionary as an associative array.
83
-	 *
84
-	 * @return array
85
-	 */
86
-	public function to_array();
87
-
88
-	/**
89
-	 * Returns a dictionary that only contains the key-value pairs which satisfy
90
-	 * $condition.
91
-	 *
92
-	 * @param callable $condition
93
-	 *
94
-	 * @return static
95
-	 */
96
-	public function filter( $condition );
97
-
98
-	/**
99
-	 * Removes all key-value pairs from the Dictionary that do not satisfy
100
-	 * $condition.
101
-	 *
102
-	 * @param callable $condition
103
-	 *
104
-	 * @return Dictionary
105
-	 */
106
-	public function reject( $condition );
107
-
108
-	/**
109
-	 * Adds the key-value pair containing $key and $value to the dictionary.
110
-	 *
111
-	 * @param mixed $key   Key to add.
112
-	 * @param mixed $value Value to add.
113
-	 *
114
-	 * @return Dictionary
115
-	 * @throws \InvalidArgumentException
116
-	 */
117
-	public function add( $key, $value );
118
-
119
-	/**
120
-	 * Applies the callback function $callable to each key-value pair in the
121
-	 * dictionary.
122
-	 *
123
-	 * @param callable $callable
124
-	 */
125
-	public function each( $callable );
126
-
127
-	/**
128
-	 * Returns the value associated with $key in the dictionary, returns
129
-	 * $default if it does not.
130
-	 *
131
-	 * @param mixed $key     Key to fetch.
132
-	 * @param mixed $default Default value if key is not found.
133
-	 *
134
-	 * @return mixed
135
-	 */
136
-	public function get_or_else( $key, $default );
137
-
138
-	/**
139
-	 * Returns an array of all keys in the dictionary.
140
-	 *
141
-	 * @return array
142
-	 */
143
-	public function keys();
144
-
145
-	/**
146
-	 * Returns an array of all values in the dictionary.
147
-	 *
148
-	 * @return array
149
-	 */
150
-	public function values();
151
-
152
-	/**
153
-	 * Returns a new dictionary with the callback function $callable applied to
154
-	 * every key-value pair in the dictionary.
155
-	 *
156
-	 * @param callable $callable
157
-	 *
158
-	 * @return static
159
-	 */
160
-	public function map( $callable );
161
-
162
-	/**
163
-	 * Adds every key-value pair in $storage to the dictionary.
164
-	 *
165
-	 * @param array|Dictionary $source Storage object to merge.
166
-	 *
167
-	 * @return static
168
-	 */
169
-	public function merge( $source );
170
-
171
-
172
-	/**
173
-	 * Reduce the dictionary to a single value. The callable should contain
174
-	 * args: carry, key, value
175
-	 *
176
-	 * @param callable $callable
177
-	 * @param mixed    $initial
178
-	 *
179
-	 * @return mixed
180
-	 */
181
-	public function reduce( $callable, $initial );
8
+    /**
9
+     * Returns the type of the dictionary's keys.
10
+     *
11
+     * @return string
12
+     */
13
+    public function get_key_type();
14
+
15
+    /**
16
+     * Returns the type of the dictionary's values.
17
+     *
18
+     * @return string
19
+     */
20
+    public function get_value_type();
21
+
22
+    /**
23
+     * Returns true if $key is in the dictionary, returns false if it is not.
24
+     *
25
+     * @param mixed $key Key to check for.
26
+     *
27
+     * @return bool
28
+     */
29
+    public function exists( $key );
30
+
31
+    /**
32
+     * Returns true if the callable returns true. The callable should accept a
33
+     * key and value as arguments and return a boolean.
34
+     *
35
+     * @param  callable $callable
36
+     * @return bool
37
+     */
38
+    public function contains( $callable );
39
+
40
+    /**
41
+     * Returns the value associated with $key.
42
+     *
43
+     * @param mixed $key Key to get.
44
+     *
45
+     * @return mixed
46
+     */
47
+    public function get( $key );
48
+
49
+    /**
50
+     * Removes the key-value pair represented by $key from the dictionary.
51
+     *
52
+     * @param mixed $key Key to remove.
53
+     *
54
+     * @return static
55
+     */
56
+    public function delete( $key );
57
+
58
+    /**
59
+     * Returns true if $value is in the dictionary, returns false if not.
60
+     *
61
+     * @param mixed $value Value to check for existence.
62
+     *
63
+     * @return bool
64
+     */
65
+    public function value_exists( $value );
66
+
67
+    /**
68
+     * Returns the number of key-value pairs in the dictionary.
69
+     *
70
+     * @return int
71
+     */
72
+    public function count();
73
+
74
+    /**
75
+     * Removes every key-value pair from the dictionary.
76
+     *
77
+     * @return static
78
+     */
79
+    public function clear();
80
+
81
+    /**
82
+     * Returns the key-value pairs in the dictionary as an associative array.
83
+     *
84
+     * @return array
85
+     */
86
+    public function to_array();
87
+
88
+    /**
89
+     * Returns a dictionary that only contains the key-value pairs which satisfy
90
+     * $condition.
91
+     *
92
+     * @param callable $condition
93
+     *
94
+     * @return static
95
+     */
96
+    public function filter( $condition );
97
+
98
+    /**
99
+     * Removes all key-value pairs from the Dictionary that do not satisfy
100
+     * $condition.
101
+     *
102
+     * @param callable $condition
103
+     *
104
+     * @return Dictionary
105
+     */
106
+    public function reject( $condition );
107
+
108
+    /**
109
+     * Adds the key-value pair containing $key and $value to the dictionary.
110
+     *
111
+     * @param mixed $key   Key to add.
112
+     * @param mixed $value Value to add.
113
+     *
114
+     * @return Dictionary
115
+     * @throws \InvalidArgumentException
116
+     */
117
+    public function add( $key, $value );
118
+
119
+    /**
120
+     * Applies the callback function $callable to each key-value pair in the
121
+     * dictionary.
122
+     *
123
+     * @param callable $callable
124
+     */
125
+    public function each( $callable );
126
+
127
+    /**
128
+     * Returns the value associated with $key in the dictionary, returns
129
+     * $default if it does not.
130
+     *
131
+     * @param mixed $key     Key to fetch.
132
+     * @param mixed $default Default value if key is not found.
133
+     *
134
+     * @return mixed
135
+     */
136
+    public function get_or_else( $key, $default );
137
+
138
+    /**
139
+     * Returns an array of all keys in the dictionary.
140
+     *
141
+     * @return array
142
+     */
143
+    public function keys();
144
+
145
+    /**
146
+     * Returns an array of all values in the dictionary.
147
+     *
148
+     * @return array
149
+     */
150
+    public function values();
151
+
152
+    /**
153
+     * Returns a new dictionary with the callback function $callable applied to
154
+     * every key-value pair in the dictionary.
155
+     *
156
+     * @param callable $callable
157
+     *
158
+     * @return static
159
+     */
160
+    public function map( $callable );
161
+
162
+    /**
163
+     * Adds every key-value pair in $storage to the dictionary.
164
+     *
165
+     * @param array|Dictionary $source Storage object to merge.
166
+     *
167
+     * @return static
168
+     */
169
+    public function merge( $source );
170
+
171
+
172
+    /**
173
+     * Reduce the dictionary to a single value. The callable should contain
174
+     * args: carry, key, value
175
+     *
176
+     * @param callable $callable
177
+     * @param mixed    $initial
178
+     *
179
+     * @return mixed
180
+     */
181
+    public function reduce( $callable, $initial );
182 182
 }
Please login to merge, or discard this patch.
src/Axolotl/Type.php 1 patch
Indentation   +154 added lines, -154 removed lines patch added patch discarded remove patch
@@ -15,158 +15,158 @@
 block discarded – undo
15 15
  */
16 16
 class Type {
17 17
 
18
-	/**
19
-	 * Type to validate against.
20
-	 *
21
-	 * @var string
22
-	 */
23
-	private $type;
24
-
25
-	/**
26
-	 * Type constructor.
27
-	 *
28
-	 * @param string $type
29
-	 * @param bool   $key_type
30
-	 */
31
-	public function __construct( $type, $key_type = false ) {
32
-		$this->type = $this->determine( $type, $key_type );
33
-	}
34
-
35
-	/**
36
-	 * Get validation type.
37
-	 *
38
-	 * @return string
39
-	 */
40
-	public function get_type() {
41
-		return $this->type;
42
-	}
43
-
44
-	/**
45
-	 * Returns whether the type is an Axolotl model.
46
-	 *
47
-	 * @return bool
48
-	 */
49
-	public function is_model() {
50
-		if ( ! class_exists( $this->type ) ) {
51
-			return false;
52
-		}
53
-
54
-		$reflection = new ReflectionClass( $this->type );
55
-		return $reflection->isSubclassOf( 'Intraxia\Jaxion\Axolotl\Model' );
56
-	}
57
-
58
-	/**
59
-	 * Create a new model from the given data.
60
-	 *
61
-	 * @param array $data Data for the model.
62
-	 *
63
-	 * @return Model
64
-	 */
65
-	public function create_model( array $data ) {
66
-		return new $this->type( $data );
67
-	}
68
-
69
-	/**
70
-	 * Validates an array of element.
71
-	 *
72
-	 * @param array $elements Elements to be validated.
73
-	 *
74
-	 * @throws InvalidArgumentException
75
-	 */
76
-	public function validate_elements( array $elements ) {
77
-		foreach ( $elements as $element ) {
78
-			$this->validate_element( $element );
79
-		}
80
-	}
81
-
82
-	/**
83
-	 * Validate whether the
84
-	 *
85
-	 * @param mixed $element Element to validate.
86
-	 *
87
-	 * @throws InvalidArgumentException
88
-	 */
89
-	public function validate_element( $element ) {
90
-		$type = gettype( $element );
91
-		$callable = $this->type === 'callable';
92
-		$is_object = 'object' === $type;
93
-		$loose_check = $this->type === 'object';
94
-
95
-		// callable must be callable
96
-		if ( $callable && ! is_callable( $element ) ) {
97
-			throw new InvalidArgumentException( 'Item must be callable' );
98
-		}
99
-
100
-		// target isn't callable, object must be an instance of target
101
-		if ( ! $loose_check && ! $callable && $is_object && ! is_a( $element, $this->type ) ) {
102
-			throw new InvalidArgumentException( "Item is not type or subtype of $this->type" );
103
-		}
104
-
105
-		// a non callable, non object type should match the target string
106
-		if ( ! $callable && ! $is_object && $type !== $this->type ) {
107
-			throw new InvalidArgumentException( "Item is not of type: $this->type" );
108
-		}
109
-	}
110
-
111
-	/**
112
-	 * Determine the type to validate against.
113
-	 *
114
-	 * @param string $type     Type to determine.
115
-	 * @param bool   $key_type Whether the type is for keys.
116
-	 *
117
-	 * @return string
118
-	 *
119
-	 * @throws InvalidArgumentException
120
-	 */
121
-	private function determine( $type, $key_type = false ) {
122
-		if ( ! $key_type && $this->non_scalar_type_exists( $type ) ) {
123
-			return $type;
124
-		}
125
-
126
-		if ( $scalar_type = $this->determine_scalar( $type ) ) {
127
-			if ( $key_type && (in_array( $scalar_type, array( 'double', 'boolean' ) )) ) {
128
-				throw new InvalidArgumentException( 'This type is not supported as a key.' );
129
-			}
130
-
131
-			return $scalar_type;
132
-		}
133
-
134
-		throw new InvalidArgumentException( 'This type does not exist.' );
135
-	}
136
-
137
-	/**
138
-	 * Determines whether the given type exists.
139
-	 *
140
-	 * @param string $type Type to check.
141
-	 *
142
-	 * @return bool
143
-	 */
144
-	private function non_scalar_type_exists( $type ) {
145
-		return class_exists( $type )
146
-				|| interface_exists( $type )
147
-				|| in_array( $type, array( 'array', 'object', 'callable' ) );
148
-	}
149
-
150
-	/**
151
-	 * Returns the type if it's scalar, otherwise, returns null.
152
-	 *
153
-	 * @param string $type Type to check.
154
-	 *
155
-	 * @return string|null
156
-	 */
157
-	private function determine_scalar( $type ) {
158
-		$synonyms = array(
159
-			'int' => 'integer',
160
-			'float' => 'double',
161
-			'bool' => 'boolean',
162
-		);
163
-
164
-		if ( array_key_exists( $type, $synonyms ) ) {
165
-			$type = $synonyms[ $type ];
166
-		}
167
-
168
-		return in_array( $type, array( 'string', 'integer', 'double', 'boolean' ) ) ?
169
-			$type :
170
-			null;
171
-	}
18
+    /**
19
+     * Type to validate against.
20
+     *
21
+     * @var string
22
+     */
23
+    private $type;
24
+
25
+    /**
26
+     * Type constructor.
27
+     *
28
+     * @param string $type
29
+     * @param bool   $key_type
30
+     */
31
+    public function __construct( $type, $key_type = false ) {
32
+        $this->type = $this->determine( $type, $key_type );
33
+    }
34
+
35
+    /**
36
+     * Get validation type.
37
+     *
38
+     * @return string
39
+     */
40
+    public function get_type() {
41
+        return $this->type;
42
+    }
43
+
44
+    /**
45
+     * Returns whether the type is an Axolotl model.
46
+     *
47
+     * @return bool
48
+     */
49
+    public function is_model() {
50
+        if ( ! class_exists( $this->type ) ) {
51
+            return false;
52
+        }
53
+
54
+        $reflection = new ReflectionClass( $this->type );
55
+        return $reflection->isSubclassOf( 'Intraxia\Jaxion\Axolotl\Model' );
56
+    }
57
+
58
+    /**
59
+     * Create a new model from the given data.
60
+     *
61
+     * @param array $data Data for the model.
62
+     *
63
+     * @return Model
64
+     */
65
+    public function create_model( array $data ) {
66
+        return new $this->type( $data );
67
+    }
68
+
69
+    /**
70
+     * Validates an array of element.
71
+     *
72
+     * @param array $elements Elements to be validated.
73
+     *
74
+     * @throws InvalidArgumentException
75
+     */
76
+    public function validate_elements( array $elements ) {
77
+        foreach ( $elements as $element ) {
78
+            $this->validate_element( $element );
79
+        }
80
+    }
81
+
82
+    /**
83
+     * Validate whether the
84
+     *
85
+     * @param mixed $element Element to validate.
86
+     *
87
+     * @throws InvalidArgumentException
88
+     */
89
+    public function validate_element( $element ) {
90
+        $type = gettype( $element );
91
+        $callable = $this->type === 'callable';
92
+        $is_object = 'object' === $type;
93
+        $loose_check = $this->type === 'object';
94
+
95
+        // callable must be callable
96
+        if ( $callable && ! is_callable( $element ) ) {
97
+            throw new InvalidArgumentException( 'Item must be callable' );
98
+        }
99
+
100
+        // target isn't callable, object must be an instance of target
101
+        if ( ! $loose_check && ! $callable && $is_object && ! is_a( $element, $this->type ) ) {
102
+            throw new InvalidArgumentException( "Item is not type or subtype of $this->type" );
103
+        }
104
+
105
+        // a non callable, non object type should match the target string
106
+        if ( ! $callable && ! $is_object && $type !== $this->type ) {
107
+            throw new InvalidArgumentException( "Item is not of type: $this->type" );
108
+        }
109
+    }
110
+
111
+    /**
112
+     * Determine the type to validate against.
113
+     *
114
+     * @param string $type     Type to determine.
115
+     * @param bool   $key_type Whether the type is for keys.
116
+     *
117
+     * @return string
118
+     *
119
+     * @throws InvalidArgumentException
120
+     */
121
+    private function determine( $type, $key_type = false ) {
122
+        if ( ! $key_type && $this->non_scalar_type_exists( $type ) ) {
123
+            return $type;
124
+        }
125
+
126
+        if ( $scalar_type = $this->determine_scalar( $type ) ) {
127
+            if ( $key_type && (in_array( $scalar_type, array( 'double', 'boolean' ) )) ) {
128
+                throw new InvalidArgumentException( 'This type is not supported as a key.' );
129
+            }
130
+
131
+            return $scalar_type;
132
+        }
133
+
134
+        throw new InvalidArgumentException( 'This type does not exist.' );
135
+    }
136
+
137
+    /**
138
+     * Determines whether the given type exists.
139
+     *
140
+     * @param string $type Type to check.
141
+     *
142
+     * @return bool
143
+     */
144
+    private function non_scalar_type_exists( $type ) {
145
+        return class_exists( $type )
146
+                || interface_exists( $type )
147
+                || in_array( $type, array( 'array', 'object', 'callable' ) );
148
+    }
149
+
150
+    /**
151
+     * Returns the type if it's scalar, otherwise, returns null.
152
+     *
153
+     * @param string $type Type to check.
154
+     *
155
+     * @return string|null
156
+     */
157
+    private function determine_scalar( $type ) {
158
+        $synonyms = array(
159
+            'int' => 'integer',
160
+            'float' => 'double',
161
+            'bool' => 'boolean',
162
+        );
163
+
164
+        if ( array_key_exists( $type, $synonyms ) ) {
165
+            $type = $synonyms[ $type ];
166
+        }
167
+
168
+        return in_array( $type, array( 'string', 'integer', 'double', 'boolean' ) ) ?
169
+            $type :
170
+            null;
171
+    }
172 172
 }
Please login to merge, or discard this patch.
src/Axolotl/Dictionary.php 1 patch
Indentation   +368 added lines, -368 removed lines patch added patch discarded remove patch
@@ -14,372 +14,372 @@
 block discarded – undo
14 14
  */
15 15
 class Dictionary implements DictionaryContract {
16 16
 
17
-	/**
18
-	 * Dictionary storage array.
19
-	 *
20
-	 * @var array
21
-	 */
22
-	protected $storage = array();
23
-
24
-	/**
25
-	 * Key Type service.
26
-	 *
27
-	 * @var Type
28
-	 */
29
-	protected $key_type;
30
-
31
-	/**
32
-	 * Value Type service.
33
-	 *
34
-	 * @var Type
35
-	 */
36
-	protected $val_type;
37
-
38
-	/**
39
-	 * Where Dictionary is in loop.
40
-	 *
41
-	 * @var int
42
-	 */
43
-	protected $position = 0;
44
-
45
-	/**
46
-	 * Dictionary keys.
47
-	 *
48
-	 * @var array
49
-	 */
50
-	protected $keys = array();
51
-
52
-	/**
53
-	 * Dictionary constructor.
54
-	 *
55
-	 * @param string $key_type
56
-	 * @param string $val_type
57
-	 * @param array  $storage
58
-	 *
59
-	 * @throws InvalidArgumentException
60
-	 */
61
-	public function __construct( $key_type, $val_type, array $storage = array() ) {
62
-		$this->key_type = new Type( $key_type, true );
63
-		$this->val_type = new Type( $val_type );
64
-
65
-		foreach ( $storage as $key => $val ) {
66
-			$this->key_type->validate_element( $key );
67
-			$this->val_type->validate_element( $val );
68
-
69
-			$this->storage[ $key ] = $val;
70
-		}
71
-	}
72
-
73
-	/**
74
-	 * {@inheritdoc}
75
-	 *
76
-	 * @return string
77
-	 */
78
-	public function get_key_type() {
79
-		return $this->key_type->get_type();
80
-	}
81
-
82
-	/**
83
-	 * {@inheritdoc}
84
-	 *
85
-	 * @return string
86
-	 */
87
-	public function get_value_type() {
88
-		return $this->val_type->get_type();
89
-	}
90
-
91
-	/**
92
-	 * {@inheritdoc}
93
-	 *
94
-	 * @param mixed $key Key to check.
95
-	 *
96
-	 * @return bool
97
-	 */
98
-	public function exists( $key ) {
99
-		return array_key_exists( $key, $this->storage );
100
-	}
101
-
102
-	/**
103
-	 * {@inheritdoc}
104
-	 *
105
-	 * @param mixed $key Key to get.
106
-	 *
107
-	 * @return mixed|null
108
-	 */
109
-	public function get( $key ) {
110
-		return $this->exists( $key ) ? $this->storage[ $key ] : null;
111
-	}
112
-
113
-	/**
114
-	 * {@inheritdoc}
115
-	 *
116
-	 * @param mixed $key Key to remove.
117
-	 *
118
-	 * @return DictionaryContract
119
-	 */
120
-	public function delete( $key ) {
121
-		$storage = $this->storage;
122
-		if ( $this->exists( $key ) ) {
123
-			unset( $storage[ $key ] );
124
-		}
125
-
126
-		return new static( $this->get_key_type(), $this->get_value_type(), $storage );
127
-	}
128
-
129
-	/**
130
-	 * {@inheritdoc}
131
-	 *
132
-	 * @param mixed $value Value to validate.
133
-	 *
134
-	 * @return bool
135
-	 */
136
-	public function value_exists( $value ) {
137
-		return in_array( $value, $this->storage );
138
-	}
139
-
140
-	/**
141
-	 * {@inheritdoc}
142
-	 */
143
-	public function count() {
144
-		return count( $this->storage );
145
-	}
146
-
147
-	/**
148
-	 * {@inheritdoc}
149
-	 */
150
-	public function clear() {
151
-		return new static( $this->get_key_type(), $this->get_value_type() );
152
-	}
153
-
154
-	/**
155
-	 * {@inheritdoc}
156
-	 *
157
-	 * @return array
158
-	 */
159
-	public function to_array() {
160
-		return $this->storage;
161
-	}
162
-
163
-	/**
164
-	 * {@inheritdoc}
165
-	 *
166
-	 * @param callable $condition Conditional callback.
167
-	 *
168
-	 * @return DictionaryContract
169
-	 */
170
-	public function filter( $condition ) {
171
-		$storage = array();
172
-
173
-		foreach ( $this->storage as $key => $value ) {
174
-			if ( call_user_func( $condition, $value, $key ) ) {
175
-				$storage[ $key ] = $value;
176
-			}
177
-		}
178
-
179
-		return new static( $this->get_key_type(), $this->get_value_type(), $storage );
180
-	}
181
-
182
-	/**
183
-	 * {@inheritdoc}
184
-	 *
185
-	 * @param callable $condition Callback condition.
186
-	 *
187
-	 * @return DictionaryContract
188
-	 */
189
-	public function reject( $condition ) {
190
-		return $this->filter( function ( $v, $k ) use ( $condition ) {
191
-			return ! call_user_func( $condition, $v, $k );
192
-		} );
193
-	}
194
-
195
-	/**
196
-	 * {@inheritdoc}
197
-	 *
198
-	 * @param mixed $key   Key to add.
199
-	 * @param mixed $value Value to add.
200
-	 *
201
-	 * @return DictionaryContract
202
-	 */
203
-	public function add( $key, $value ) {
204
-		$storage         = $this->storage;
205
-		$storage[ $key ] = $value;
206
-
207
-		return new static( $this->get_key_type(), $this->get_value_type(), $storage );
208
-	}
209
-
210
-	/**
211
-	 * {@inheritdoc}
212
-	 *
213
-	 * @param callable $callable Function to call.
214
-	 */
215
-	public function each( $callable ) {
216
-		foreach ( $this->storage as $key => $value ) {
217
-			call_user_func( $callable, $value, $key );
218
-		}
219
-	}
220
-
221
-	/**
222
-	 * {@inheritdoc}
223
-	 *
224
-	 * @param mixed $key     Key to fetch.
225
-	 * @param mixed $default Default to return if key is missing.
226
-	 *
227
-	 * @return mixed
228
-	 */
229
-	public function get_or_else( $key, $default ) {
230
-		return ( $this->exists( $key ) ) ? $this->get( $key ) : $default;
231
-	}
232
-
233
-	/**
234
-	 * {@inheritdoc}
235
-	 */
236
-	public function keys() {
237
-		return array_keys( $this->storage );
238
-	}
239
-
240
-	/**
241
-	 * {@inheritdoc}
242
-	 */
243
-	public function values() {
244
-		return array_values( $this->storage );
245
-	}
246
-
247
-	/**
248
-	 * {@inheritdoc}
249
-	 *
250
-	 * @param callable $callable Function to call.
251
-	 *
252
-	 * @return DictionaryContract
253
-	 */
254
-	public function map( $callable ) {
255
-		$items = array();
256
-		$val_type = null;
257
-
258
-		foreach ( $this->storage as $key => $val ) {
259
-			$v = call_user_func( $callable, $val, $key );
260
-
261
-			if ( ! isset( $val_type ) ) {
262
-				$val_type = gettype( $v );
263
-			}
264
-
265
-			$items[ $key ] = $v;
266
-		}
267
-
268
-		return new static( $this->get_key_type(), $val_type, $items );
269
-	}
270
-
271
-	/**
272
-	 * {@inheritdoc}
273
-	 *
274
-	 * @param array|DictionaryContract $source Source to merge.
275
-	 *
276
-	 * @return DictionaryContract
277
-	 *
278
-	 * @throws InvalidArgumentException
279
-	 */
280
-	public function merge( $source ) {
281
-		if ( $source instanceof self ) {
282
-			$source = $source->to_array();
283
-		}
284
-
285
-		if ( ! is_array( $source ) ) {
286
-			throw new InvalidArgumentException( 'Combine must be a Dictionary or an array' );
287
-		}
288
-
289
-		return new static( $this->get_key_type(), $this->get_value_type(), array_merge( $this->storage, $source ) );
290
-	}
291
-
292
-
293
-	/**
294
-	 * {@inheritdoc}
295
-	 *
296
-	 * @param callable $callable
297
-	 *
298
-	 * @return bool
299
-	 */
300
-	public function contains( $callable ) {
301
-		foreach ( $this->storage as $key => $value ) {
302
-			if ( call_user_func( $callable, $value, $key ) ) {
303
-				return true;
304
-			}
305
-		}
306
-
307
-		return false;
308
-	}
309
-
310
-	/**
311
-	 * {@inheritdoc}
312
-	 *
313
-	 * @param callable $callable
314
-	 * @param mixed    $initial
315
-	 *
316
-	 * @return mixed
317
-	 */
318
-	public function reduce( $callable, $initial ) {
319
-		$carry = $initial;
320
-
321
-		foreach ( $this->storage as $key => $value ) {
322
-			$carry = $callable( $carry, $value, $key );
323
-		}
324
-
325
-		return $carry;
326
-	}
327
-
328
-	/**
329
-	 * Return the current element.
330
-	 *
331
-	 * @return mixed
332
-	 */
333
-	public function current() {
334
-		$key = $this->keys[ $this->position ];
335
-		return $this->storage[ $key ];
336
-	}
337
-
338
-	/**
339
-	 * Move forward to next element.
340
-	 */
341
-	public function next() {
342
-		$this->position ++;
343
-	}
344
-
345
-	/**
346
-	 * Return the key of the current element.
347
-	 *
348
-	 * @return mixed
349
-	 */
350
-	public function key() {
351
-		return $this->keys[ $this->position ];
352
-	}
353
-
354
-	/**
355
-	 * Checks if current position is valid.
356
-	 *
357
-	 * @return bool
358
-	 */
359
-	public function valid() {
360
-		return isset( $this->keys[ $this->position ] );
361
-	}
362
-
363
-	/**
364
-	 * Rewind the Iterator to the first element.
365
-	 */
366
-	public function rewind() {
367
-		$this->position = 0;
368
-		$this->keys = array_keys( $this->storage );
369
-	}
370
-
371
-	/**
372
-	 * {@inheritDoc}
373
-	 *
374
-	 * @return array
375
-	 */
376
-	public function serialize() {
377
-		return $this->map(function( $val ) {
378
-			if ( $val instanceof Serializes ) {
379
-				$val = $val->serialize();
380
-			}
381
-
382
-			return $val;
383
-		})->to_array();
384
-	}
17
+    /**
18
+     * Dictionary storage array.
19
+     *
20
+     * @var array
21
+     */
22
+    protected $storage = array();
23
+
24
+    /**
25
+     * Key Type service.
26
+     *
27
+     * @var Type
28
+     */
29
+    protected $key_type;
30
+
31
+    /**
32
+     * Value Type service.
33
+     *
34
+     * @var Type
35
+     */
36
+    protected $val_type;
37
+
38
+    /**
39
+     * Where Dictionary is in loop.
40
+     *
41
+     * @var int
42
+     */
43
+    protected $position = 0;
44
+
45
+    /**
46
+     * Dictionary keys.
47
+     *
48
+     * @var array
49
+     */
50
+    protected $keys = array();
51
+
52
+    /**
53
+     * Dictionary constructor.
54
+     *
55
+     * @param string $key_type
56
+     * @param string $val_type
57
+     * @param array  $storage
58
+     *
59
+     * @throws InvalidArgumentException
60
+     */
61
+    public function __construct( $key_type, $val_type, array $storage = array() ) {
62
+        $this->key_type = new Type( $key_type, true );
63
+        $this->val_type = new Type( $val_type );
64
+
65
+        foreach ( $storage as $key => $val ) {
66
+            $this->key_type->validate_element( $key );
67
+            $this->val_type->validate_element( $val );
68
+
69
+            $this->storage[ $key ] = $val;
70
+        }
71
+    }
72
+
73
+    /**
74
+     * {@inheritdoc}
75
+     *
76
+     * @return string
77
+     */
78
+    public function get_key_type() {
79
+        return $this->key_type->get_type();
80
+    }
81
+
82
+    /**
83
+     * {@inheritdoc}
84
+     *
85
+     * @return string
86
+     */
87
+    public function get_value_type() {
88
+        return $this->val_type->get_type();
89
+    }
90
+
91
+    /**
92
+     * {@inheritdoc}
93
+     *
94
+     * @param mixed $key Key to check.
95
+     *
96
+     * @return bool
97
+     */
98
+    public function exists( $key ) {
99
+        return array_key_exists( $key, $this->storage );
100
+    }
101
+
102
+    /**
103
+     * {@inheritdoc}
104
+     *
105
+     * @param mixed $key Key to get.
106
+     *
107
+     * @return mixed|null
108
+     */
109
+    public function get( $key ) {
110
+        return $this->exists( $key ) ? $this->storage[ $key ] : null;
111
+    }
112
+
113
+    /**
114
+     * {@inheritdoc}
115
+     *
116
+     * @param mixed $key Key to remove.
117
+     *
118
+     * @return DictionaryContract
119
+     */
120
+    public function delete( $key ) {
121
+        $storage = $this->storage;
122
+        if ( $this->exists( $key ) ) {
123
+            unset( $storage[ $key ] );
124
+        }
125
+
126
+        return new static( $this->get_key_type(), $this->get_value_type(), $storage );
127
+    }
128
+
129
+    /**
130
+     * {@inheritdoc}
131
+     *
132
+     * @param mixed $value Value to validate.
133
+     *
134
+     * @return bool
135
+     */
136
+    public function value_exists( $value ) {
137
+        return in_array( $value, $this->storage );
138
+    }
139
+
140
+    /**
141
+     * {@inheritdoc}
142
+     */
143
+    public function count() {
144
+        return count( $this->storage );
145
+    }
146
+
147
+    /**
148
+     * {@inheritdoc}
149
+     */
150
+    public function clear() {
151
+        return new static( $this->get_key_type(), $this->get_value_type() );
152
+    }
153
+
154
+    /**
155
+     * {@inheritdoc}
156
+     *
157
+     * @return array
158
+     */
159
+    public function to_array() {
160
+        return $this->storage;
161
+    }
162
+
163
+    /**
164
+     * {@inheritdoc}
165
+     *
166
+     * @param callable $condition Conditional callback.
167
+     *
168
+     * @return DictionaryContract
169
+     */
170
+    public function filter( $condition ) {
171
+        $storage = array();
172
+
173
+        foreach ( $this->storage as $key => $value ) {
174
+            if ( call_user_func( $condition, $value, $key ) ) {
175
+                $storage[ $key ] = $value;
176
+            }
177
+        }
178
+
179
+        return new static( $this->get_key_type(), $this->get_value_type(), $storage );
180
+    }
181
+
182
+    /**
183
+     * {@inheritdoc}
184
+     *
185
+     * @param callable $condition Callback condition.
186
+     *
187
+     * @return DictionaryContract
188
+     */
189
+    public function reject( $condition ) {
190
+        return $this->filter( function ( $v, $k ) use ( $condition ) {
191
+            return ! call_user_func( $condition, $v, $k );
192
+        } );
193
+    }
194
+
195
+    /**
196
+     * {@inheritdoc}
197
+     *
198
+     * @param mixed $key   Key to add.
199
+     * @param mixed $value Value to add.
200
+     *
201
+     * @return DictionaryContract
202
+     */
203
+    public function add( $key, $value ) {
204
+        $storage         = $this->storage;
205
+        $storage[ $key ] = $value;
206
+
207
+        return new static( $this->get_key_type(), $this->get_value_type(), $storage );
208
+    }
209
+
210
+    /**
211
+     * {@inheritdoc}
212
+     *
213
+     * @param callable $callable Function to call.
214
+     */
215
+    public function each( $callable ) {
216
+        foreach ( $this->storage as $key => $value ) {
217
+            call_user_func( $callable, $value, $key );
218
+        }
219
+    }
220
+
221
+    /**
222
+     * {@inheritdoc}
223
+     *
224
+     * @param mixed $key     Key to fetch.
225
+     * @param mixed $default Default to return if key is missing.
226
+     *
227
+     * @return mixed
228
+     */
229
+    public function get_or_else( $key, $default ) {
230
+        return ( $this->exists( $key ) ) ? $this->get( $key ) : $default;
231
+    }
232
+
233
+    /**
234
+     * {@inheritdoc}
235
+     */
236
+    public function keys() {
237
+        return array_keys( $this->storage );
238
+    }
239
+
240
+    /**
241
+     * {@inheritdoc}
242
+     */
243
+    public function values() {
244
+        return array_values( $this->storage );
245
+    }
246
+
247
+    /**
248
+     * {@inheritdoc}
249
+     *
250
+     * @param callable $callable Function to call.
251
+     *
252
+     * @return DictionaryContract
253
+     */
254
+    public function map( $callable ) {
255
+        $items = array();
256
+        $val_type = null;
257
+
258
+        foreach ( $this->storage as $key => $val ) {
259
+            $v = call_user_func( $callable, $val, $key );
260
+
261
+            if ( ! isset( $val_type ) ) {
262
+                $val_type = gettype( $v );
263
+            }
264
+
265
+            $items[ $key ] = $v;
266
+        }
267
+
268
+        return new static( $this->get_key_type(), $val_type, $items );
269
+    }
270
+
271
+    /**
272
+     * {@inheritdoc}
273
+     *
274
+     * @param array|DictionaryContract $source Source to merge.
275
+     *
276
+     * @return DictionaryContract
277
+     *
278
+     * @throws InvalidArgumentException
279
+     */
280
+    public function merge( $source ) {
281
+        if ( $source instanceof self ) {
282
+            $source = $source->to_array();
283
+        }
284
+
285
+        if ( ! is_array( $source ) ) {
286
+            throw new InvalidArgumentException( 'Combine must be a Dictionary or an array' );
287
+        }
288
+
289
+        return new static( $this->get_key_type(), $this->get_value_type(), array_merge( $this->storage, $source ) );
290
+    }
291
+
292
+
293
+    /**
294
+     * {@inheritdoc}
295
+     *
296
+     * @param callable $callable
297
+     *
298
+     * @return bool
299
+     */
300
+    public function contains( $callable ) {
301
+        foreach ( $this->storage as $key => $value ) {
302
+            if ( call_user_func( $callable, $value, $key ) ) {
303
+                return true;
304
+            }
305
+        }
306
+
307
+        return false;
308
+    }
309
+
310
+    /**
311
+     * {@inheritdoc}
312
+     *
313
+     * @param callable $callable
314
+     * @param mixed    $initial
315
+     *
316
+     * @return mixed
317
+     */
318
+    public function reduce( $callable, $initial ) {
319
+        $carry = $initial;
320
+
321
+        foreach ( $this->storage as $key => $value ) {
322
+            $carry = $callable( $carry, $value, $key );
323
+        }
324
+
325
+        return $carry;
326
+    }
327
+
328
+    /**
329
+     * Return the current element.
330
+     *
331
+     * @return mixed
332
+     */
333
+    public function current() {
334
+        $key = $this->keys[ $this->position ];
335
+        return $this->storage[ $key ];
336
+    }
337
+
338
+    /**
339
+     * Move forward to next element.
340
+     */
341
+    public function next() {
342
+        $this->position ++;
343
+    }
344
+
345
+    /**
346
+     * Return the key of the current element.
347
+     *
348
+     * @return mixed
349
+     */
350
+    public function key() {
351
+        return $this->keys[ $this->position ];
352
+    }
353
+
354
+    /**
355
+     * Checks if current position is valid.
356
+     *
357
+     * @return bool
358
+     */
359
+    public function valid() {
360
+        return isset( $this->keys[ $this->position ] );
361
+    }
362
+
363
+    /**
364
+     * Rewind the Iterator to the first element.
365
+     */
366
+    public function rewind() {
367
+        $this->position = 0;
368
+        $this->keys = array_keys( $this->storage );
369
+    }
370
+
371
+    /**
372
+     * {@inheritDoc}
373
+     *
374
+     * @return array
375
+     */
376
+    public function serialize() {
377
+        return $this->map(function( $val ) {
378
+            if ( $val instanceof Serializes ) {
379
+                $val = $val->serialize();
380
+            }
381
+
382
+            return $val;
383
+        })->to_array();
384
+    }
385 385
 }
Please login to merge, or discard this patch.