Completed
Push — master ( 72a657...653b9d )
by Andrii
02:10
created

TreeConverter::getCalculator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
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, 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 2
    public function __construct($path = null)
39
    {
40 2
        if ($path === null) {
41 2
            $path = __DIR__ . '/../../res/units-tree.php';
42
        }
43
44 2
        $this->data = require $path;
45 2
    }
46
47 4
    private function findData($name)
48
    {
49 4
        if (!isset($this->data[$name])) {
50
            throw new NotConvertibleException('no data for: ' . $name);
51
        }
52
53 4
        return $this->data[$name];
54
    }
55
56 1
    public function equals(UnitInterface $unit, UnitInterface $other)
57
    {
58 1
        return $this->getNode($unit)->equals($other);
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64 2
    public function getCalculator(UnitInterface $unit)
65
    {
66 2
        return $this->getNode($unit)->getCalculator();
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72 2
    public function isConvertible(UnitInterface $unit, UnitInterface $other)
73
    {
74 2
        return $this->getNode($unit)->isConvertible($other);
75
    }
76
77 3
    public function getMeasure(UnitInterface $unit)
78
    {
79 3
        return $this->getNode($unit)->getMeasure();
80
    }
81
82
    /**
83
     * {@inheritdoc}
84
     */
85 4
    public function convert(UnitInterface $unit, UnitInterface $other, $quantity)
86
    {
87 4
        return $this->getNode($unit)->convert($other, $quantity);
88
    }
89
90
    /**
91
     * @var NodeUnit[]
92
     */
93
    private $nodes;
94
95
    /**
96
     * Returns tree unit by name or unit.
97
     * @param string|UnitInterface
98
     * @return NodeUnit
99
     */
100 9
    public function getNode($unit)
101
    {
102 9
        $name = $unit instanceof UnitInterface ? $unit->getName() : $unit;
103
104 9
        if (!isset($this->nodes[$name])) {
105 4
            $this->nodes[$name] = $this->findNode($name);
106
        }
107
108 9
        return $this->nodes[$name];
109
    }
110
111 4
    private function findNode($name)
112
    {
113 4
        $data = $this->findData($name);
114
115 4
        if (isset($data['parent'])) {
116 4
            $parent = $data['parent'];
117
        } else {
118
            throw new NotConvertibleException("no parent for: $name");
119
        }
120
121 4
        if ($parent === '') {
122 3
            return new RootUnit($this, $name);
123
        }
124
125 4
        if (isset($data['method'])) {
126
            $method = $data['method'];
127 4
        } elseif (isset($data['factor'])) {
128 4
            $method = $data['factor'];
129
        } else {
130
            throw new NotConvertibleException("no method for: $name");
131
        }
132
133 4
        return new NodeUnit($this, $name, $this->getNode($parent), $method);
134
    }
135
}
136