Calculatable::calculate()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 3
cts 3
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 11
nc 2
nop 3
crap 2
1
<?php namespace Arcanedev\Units\Traits;
2
3
use Arcanedev\Units\Contracts\UnitMeasure;
4
5
/**
6
 * Trait     Calculatable
7
 *
8
 * @package  Arcanedev\Units\Traits
9
 * @author   ARCANEDEV <[email protected]>
10
 */
11
trait Calculatable
12
{
13
    /* -----------------------------------------------------------------
14
     |  Getters & Setters
15
     | -----------------------------------------------------------------
16
     */
17
18
    /**
19
     * Get the unit value.
20
     *
21
     * @return float|int
22
     */
23
    abstract public function value();
24
25
    /**
26
     * Set the unit value.
27
     *
28
     * @param  float|int  $value
29
     *
30
     * @return \Arcanedev\Units\Contracts\UnitMeasure
31
     */
32
    abstract public function setValue($value);
33
34
    /**
35
     * Get the unit key.
36
     *
37
     * @return string
38
     */
39
    abstract public function unit();
40
41
    /* -----------------------------------------------------------------
42
     |  Main Methods
43
     | -----------------------------------------------------------------
44
     */
45
46
    /**
47
     * Add the unit instance.
48
     *
49
     * @param  \Arcanedev\Units\Contracts\UnitMeasure  $unit
50
     *
51
     * @return \Arcanedev\Units\Contracts\UnitMeasure
52
     */
53 48
    public function add(UnitMeasure $unit)
54
    {
55 48
        return $this->setValue(
56 48
            static::calculate(
57 48
                $this->value(), '+', $unit->to($this->unit())->value()
58
            )
59
        );
60
    }
61
62
    /**
63
     * Sub the unit instance.
64
     *
65
     * @param  \Arcanedev\Units\Contracts\UnitMeasure  $unit
66
     *
67
     * @return \Arcanedev\Units\Contracts\UnitMeasure
68
     */
69 24
    public function sub(UnitMeasure $unit)
70
    {
71 24
        return $this->setValue(
72 24
            static::calculate(
73 24
                $this->value(), '-', $unit->to($this->unit())->value()
74
            )
75
        );
76
    }
77
78
    /**
79
     * Multiply unit by the given number.
80
     *
81
     * @param  float|int  $number
82
     *
83
     * @return \Arcanedev\Units\Contracts\UnitMeasure
84
     */
85 24
    public function multiply($number)
86
    {
87 24
        return $this->setValue(
88 24
            static::calculate($this->value(), 'x', $number)
89
        );
90
    }
91
92
    /**
93
     * Divide unit by the given number.
94
     *
95
     * @param  float|int  $number
96
     *
97
     * @return \Arcanedev\Units\Contracts\UnitMeasure
98
     */
99 24
    public function divide($number)
100
    {
101 24
        return $this->setValue(
102 24
            static::calculate($this->value(), '/', $number)
103
        );
104
    }
105
106
    /**
107
     * Calculate the value.
108
     *
109
     * @param  float|int  $a
110
     * @param  string     $operator
111
     * @param  float|int  $b
112
     *
113
     * @return float|int
114
     */
115
    protected static function calculate($a, $operator, $b)
116
    {
117
        $operations = [
118
            '+' => function ($a, $b) { return $a + $b; },
119
            '-' => function ($a, $b) { return $a - $b; },
120
            'x' => function ($a, $b) { return $a * $b; },
121
            '*' => function ($a, $b) { return $a * $b; },
122
            '/' => function ($a, $b) { return $a / $b; },
123
            '^' => function ($a, $b) { return pow($a, $b); },
124
        ];
125
126 141
        return array_key_exists($operator, $operations)
127 141
            ? call_user_func_array($operations[$operator], [$a, $b])
128 129
            : $a;
129
    }
130
}
131