Completed
Push — master ( 9b22ab...6029c9 )
by Andrii
01:55
created

TreeConverter::findData()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 4
cts 4
cp 1
rs 9.9
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
/**
3
 * PHP Units of Measure Library
4
 *
5
 * @link      https://github.com/hiqdev/php-units
6
 * @package   php-units
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2017-2018, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\php\units\tree;
12
13
use hiqdev\php\units\ConverterInterface;
14
use hiqdev\php\units\exceptions\NotConvertibleException;
15
use hiqdev\php\units\UnitInterface;
16
17
/**
18
 * Tree Converter.
19
 *
20
 * Uses node units to keep units info in a tree form:
21
 *
22
 * - bit:           parent=bit          factor  = 1
23
 * - byte:          parent=bit          factor  = 1
24
 * - megabyte:      parent=byte         factor  = 10^6 = 1000000
25
 * - mebibyte:      parent=byte         factor  = 2^20 = 1048576.
26
 *
27
 * - temperature:   parent=temperature  factor  = 1
28
 * - celcius:       parent=temperature  factor  = 1
29
 * - fahrenheit:    parent=temperature  method  = function ($x) { return ($x-32)*5/9; }
30
 * - kelvin:        parent=temperature  method  = function ($x) { return $x+273.16; }
31
 *
32
 * @author Andrii Vasyliev <[email protected]>
33
 */
34
class TreeConverter implements ConverterInterface
35
{
36
    private $data;
37
38 1
    public function __construct($path = null)
39
    {
40 1
        if ($path === null) {
41 1
            $path = __DIR__ . '/../../res/units-tree.php';
42
        }
43
44 1
        $this->data = require $path;
45 1
    }
46
47 5
    private function findData($name)
48
    {
49 5
        if (!isset($this->data[$name])) {
50
            return [
51 1
                'parent' => '',
52
                'factor' => 1,
53
            ];
54
        }
55
56 5
        return $this->data[$name];
57
    }
58
59 2
    public function equals(UnitInterface $unit, UnitInterface $other)
60
    {
61 2
        return $this->getNode($unit)->equals($other);
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67 5
    public function getCalculator(UnitInterface $unit)
68
    {
69 5
        return $this->getNode($unit)->getCalculator();
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75 2
    public function isConvertible(UnitInterface $unit, UnitInterface $other)
76
    {
77 2
        return $this->getNode($unit)->isConvertible($other);
78
    }
79
80
    /**
81
     * {@inheritdoc}
82
     */
83 10
    public function getMeasure(UnitInterface $unit)
84
    {
85 10
        return $this->getNode($unit)->getMeasure();
86
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91 7
    public function convert(UnitInterface $unit, UnitInterface $other, $quantity)
92
    {
93 7
        return $this->getNode($unit)->convert($other, $quantity);
94
    }
95
96
    /**
97
     * @var NodeUnit[]
98
     */
99
    private $nodes;
100
101
    /**
102
     * Returns tree unit by name or unit.
103
     * @param string|UnitInterface
104
     * @return NodeUnit
105
     */
106 13
    public function getNode($unit)
107
    {
108 13
        $name = $unit instanceof UnitInterface ? $unit->getName() : $unit;
109
110 13
        if (!isset($this->nodes[$name])) {
111 5
            $this->nodes[$name] = $this->findNode($name);
112
        }
113
114 13
        return $this->nodes[$name];
115
    }
116
117 5
    private function findNode($name)
118
    {
119 5
        $data = $this->findData($name);
120
121 5
        if (isset($data['parent'])) {
122 5
            $parent = $data['parent'];
123
        } else {
124
            throw new NotConvertibleException("no parent for: $name");
125
        }
126
127 5
        if ($parent === '') {
128 5
            return new RootUnit($this, $name);
129
        }
130
131 5
        if (isset($data['method'])) {
132
            $method = $data['method'];
133 5
        } elseif (isset($data['factor'])) {
134 5
            $method = $data['factor'];
135
        } else {
136
            throw new NotConvertibleException("no method for: $name");
137
        }
138
139 5
        return new NodeUnit($this, $name, $this->getNode($parent), $method);
140
    }
141
}
142