Completed
Push — master ( 95e794...553f1a )
by Josh
04:13
created

Builder::isEmpty()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 2
eloc 2
nc 2
nop 1
crap 2
1
<?php
2
3
/**
4
* @package   s9e\RegexpBuilder
5
* @copyright Copyright (c) 2016 The s9e Authors
6
* @license   http://www.opensource.org/licenses/mit-license.php The MIT License
7
*/
8
namespace s9e\RegexpBuilder;
9
10
use s9e\RegexpBuilder\Input\InputInterface;
11
use s9e\RegexpBuilder\Output\OutputInterface;
12
use s9e\RegexpBuilder\Passes\CoalesceSingleCharacterPrefix;
13
use s9e\RegexpBuilder\Passes\GroupSingleCharacters;
14
use s9e\RegexpBuilder\Passes\MergePrefix;
15
use s9e\RegexpBuilder\Passes\MergeSuffix;
16
use s9e\RegexpBuilder\Passes\PromoteSingleStrings;
17
use s9e\RegexpBuilder\Passes\Recurse;
18
19
class Builder
20
{
21
	/**
22
	* @var InputInterface
23
	*/
24
	protected $input;
25
26
	/**
27
	* @var Runner
28
	*/
29
	protected $runner;
30
31
	/**
32
	* @var Serializer
33
	*/
34
	protected $serializer;
35
36
	/**
37
	* @param array $config
38
	*/
39 9
	public function __construct(array $config = [])
40
	{
41
		$config += [
42 9
			'delimiter' => '/',
43
			'input'     => 'Bytes',
44
			'output'    => 'Bytes'
45
		];
46
47 9
		$this->setInput($config['input']);
48 9
		$this->setSerializer($config['output'], $config['delimiter']);
49 9
		$this->setRunner();
50 9
	}
51
52
	/**
53
	* Build and return a regular expression that matches all of the given strings
54
	*
55
	* @param  string[] $strings Literal strings to be matched
56
	* @return string            Regular expression (without delimiters)
57
	*/
58 9
	public function build(array $strings)
59
	{
60 9
		$strings = array_unique($strings);
61 9
		if ($this->isEmpty($strings))
62
		{
63 1
			return '';
64
		}
65
66 8
		$strings = $this->splitStrings($strings);
67 8
		usort($strings, __CLASS__ . '::compareStrings');
68 8
		$strings = $this->runner->run($strings);
69
70 8
		return $this->serializer->serializeStrings($strings);
71
	}
72
73
	/**
74
	* Compare two split strings
75
	*
76
	* Will sort strings in ascending order
77
	*
78
	* @param  integer[] $a
79
	* @param  integer[] $b
80
	* @return integer
81
	*/
82 8
	protected function compareStrings(array $a, array $b)
83
	{
84 8
		$i   = -1;
85 8
		$cnt = min(count($a), count($b));
86 8
		while (++$i < $cnt)
87
		{
88 8
			if ($a[$i] !== $b[$i])
89
			{
90 8
				return $a[$i] - $b[$i];
91
			}
92
		}
93
94
		return count($a) - count($b);
95
	}
96
97
	/**
98
	* Test whether the list of strings is empty
99
	*
100
	* @param  string[] $strings
101
	* @return bool
102
	*/
103 9
	protected function isEmpty(array $strings)
104
	{
105 9
		return (empty($strings) || $strings === ['']);
106
	}
107
108
	/**
109
	* Set the InputInterface instance in $this->input
110
	*
111
	* @param  string $inputType
112
	* @return void
113
	*/
114 9
	protected function setInput($inputType)
115
	{
116 9
		$className   = __NAMESPACE__ . '\\Input\\' . $inputType;
117 9
		$this->input = new $className;
118 9
	}
119
120
	/**
121
	* Set the Runner instance $in this->runner
122
	*
123
	* @return void
124
	*/
125 9
	protected function setRunner()
126
	{
127 9
		$this->runner = new Runner;
128 9
		$this->runner->addPass(new MergePrefix);
129 9
		$this->runner->addPass(new GroupSingleCharacters);
130 9
		$this->runner->addPass(new Recurse($this->runner));
131 9
		$this->runner->addPass(new PromoteSingleStrings);
132 9
		$this->runner->addPass(new MergeSuffix);
133 9
		$this->runner->addPass(new CoalesceSingleCharacterPrefix);
134 9
	}
135
136
	/**
137
	* Set the Serializer instance in $this->serializer
138
	*
139
	* @param  string $outputType
140
	* @param  string $delimiter
141
	* @return void
142
	*/
143 9
	protected function setSerializer($outputType, $delimiter)
144
	{
145 9
		$className = __NAMESPACE__ . '\\Output\\' . $outputType;
146 9
		$output    = new $className;
147 9
		$escaper   = new Escaper($delimiter);
148
149 9
		$this->serializer = new Serializer($output, $escaper);
150 9
	}
151
152
	/**
153
	* Split all given strings by character
154
	*
155
	* @param  string[] $strings List of strings
156
	* @return array[]           List of arrays
157
	*/
158 8
	protected function splitStrings(array $strings)
159
	{
160 8
		return array_map([$this->input, 'split'], $strings);
161
	}
162
}