Completed
Push — master ( c8acae...50e3b5 )
by Josh
07:08
created

Builder::setInput()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
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 ($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
	* Set the InputInterface instance in $this->input
99
	*
100
	* @param  string $inputType
101
	* @return void
102
	*/
103 9
	protected function setInput($inputType)
104
	{
105 9
		$className   = __NAMESPACE__ . '\\Input\\' . $inputType;
106 9
		$this->input = new $className;
107 9
	}
108
109
	/**
110
	* Set the Runner instance $in this->runner
111
	*
112
	* @return void
113
	*/
114 9
	protected function setRunner()
115
	{
116 9
		$this->runner = new Runner;
117 9
		$this->runner->addPass(new MergePrefix);
118 9
		$this->runner->addPass(new GroupSingleCharacters);
119 9
		$this->runner->addPass(new Recurse($this->runner));
120 9
		$this->runner->addPass(new PromoteSingleStrings);
121 9
		$this->runner->addPass(new MergeSuffix);
122 9
		$this->runner->addPass(new CoalesceSingleCharacterPrefix);
123 9
	}
124
125
	/**
126
	* Set the Serializer instance in $this->serializer
127
	*
128
	* @param  string $outputType
129
	* @param  string $delimiter
130
	* @return void
131
	*/
132 9
	protected function setSerializer($outputType, $delimiter)
133
	{
134 9
		$className = __NAMESPACE__ . '\\Output\\' . $outputType;
135 9
		$output    = new $className;
136 9
		$escaper   = new Escaper($delimiter);
137
138 9
		$this->serializer = new Serializer($output, $escaper);
139 9
	}
140
141
	/**
142
	* Split all given strings by character
143
	*
144
	* @param  string[] $strings List of strings
145
	* @return array[]           List of arrays
146
	*/
147 8
	protected function splitStrings(array $strings)
148
	{
149 8
		return array_map([$this->input, 'split'], $strings);
150
	}
151
}