Completed
Push — master ( d62f94...2c3725 )
by Jordan
15s queued 13s
created

InputNormalizationTrait::translateToObjects()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 8
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 15
ccs 9
cts 9
cp 1
crap 3
rs 10
1
<?php
2
3
namespace Samsara\Fermat\Core\Types\Traits;
4
5
use Samsara\Exceptions\SystemError\LogicalError\IncompatibleObjectState;
6
use Samsara\Exceptions\UsageError\IntegrityConstraint;
7
use Samsara\Fermat\Complex\ComplexNumbers;
8
use Samsara\Fermat\Complex\Types\Base\Interfaces\Numbers\ComplexNumberInterface;
9
use Samsara\Fermat\Complex\Types\ComplexNumber;
10
use Samsara\Fermat\Complex\Values\ImmutableComplexNumber;
11
use Samsara\Fermat\Complex\Values\MutableComplexNumber;
0 ignored issues
show
Bug introduced by
The type Samsara\Fermat\Complex\Values\MutableComplexNumber was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Samsara\Fermat\Core\Enums\CalcMode;
13
use Samsara\Fermat\Core\Enums\NumberBase;
14
use Samsara\Fermat\Core\Numbers;
15
use Samsara\Fermat\Core\Types\Base\Interfaces\Numbers\FractionInterface;
16
use Samsara\Fermat\Core\Types\Decimal;
0 ignored issues
show
Bug introduced by
The type Samsara\Fermat\Core\Types\Decimal was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Samsara\Fermat\Core\Types\Fraction;
0 ignored issues
show
Bug introduced by
The type Samsara\Fermat\Core\Types\Fraction was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use Samsara\Fermat\Core\Types\Traits\Arithmetic\ArithmeticHelperSimpleTrait;
0 ignored issues
show
Bug introduced by
The type Samsara\Fermat\Core\Type...hmeticHelperSimpleTrait was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use Samsara\Fermat\Core\Values\ImmutableDecimal;
20
use Samsara\Fermat\Core\Values\ImmutableFraction;
21
use Samsara\Fermat\Core\Values\MutableDecimal;
22
use Samsara\Fermat\Core\Values\MutableFraction;
23
24
/**
25
 *
26
 */
27
trait InputNormalizationTrait
28
{
29
30
    /**
31
     * @param ImmutableDecimal|ImmutableFraction|ImmutableComplexNumber $partThis
32
     * @param ImmutableDecimal|ImmutableFraction|ImmutableComplexNumber $compareTo
33
     * @param int $identity
34
     * @param CalcMode|null $mode
35
     * @return ImmutableDecimal[]|ImmutableFraction[]
36
     * @throws IntegrityConstraint
37
     */
38 266
    protected static function partSelector(
39
        ImmutableDecimal|ImmutableFraction|ImmutableComplexNumber $partThis,
40
        ImmutableDecimal|ImmutableFraction|ImmutableComplexNumber $compareTo,
41
        int $identity,
42
        ?CalcMode $mode
43
    ): array
44
    {
45
46 266
        if ($partThis->isComplex()) {
47 242
            $realPart = self::normalizeObject($partThis->getRealPart(), $mode);
48 242
            $imaginaryPart = self::normalizeObject($partThis->getImaginaryPart(), $mode);
49 154
        } elseif ($partThis->isReal()) {
50 134
            $realPart = match (true) {
51 134
                $partThis instanceof Fraction => match (true) {
52
                    $compareTo instanceof Fraction => self::normalizeObject($partThis, $mode),
53
                    default => self::normalizeObject($partThis->asDecimal(), $mode)
54
                },
55 134
                $partThis instanceof Decimal => self::normalizeObject($partThis, $mode)
56
            };
57 134
            $imaginaryPart = match (true) {
58 134
                $compareTo instanceof Fraction => (new ImmutableFraction(
59
                    new ImmutableDecimal(
60
                        $identity.'i',
61
                        $compareTo->getNumerator()->getScale()
62
                    ),
63
                    new ImmutableDecimal(
64
                        1,
65
                        $compareTo->getDenominator()->getScale()
66
                    ),
67
                    $compareTo->getBase()
68
                ))->setMode($mode),
69 134
                default => (new ImmutableDecimal(
70 134
                    $identity.'i',
71 134
                    $compareTo->getScale()
72 134
                ))->setMode($mode)
73
            };
74
        } else {
75 146
            $realPart = match (true) {
76 146
                $compareTo instanceof Fraction => (new ImmutableFraction(
77
                    new ImmutableDecimal(
78
                        $identity,
79
                        $compareTo->getNumerator()->getScale()
80
                    ),
81
                    new ImmutableDecimal(
82
                        1,
83
                        $compareTo->getDenominator()->getScale()
84
                    ),
85
                    $compareTo->getBase()
86
                ))->setMode($mode),
87 146
                default => (new ImmutableDecimal(
88
                    $identity,
89 146
                    $compareTo->getScale()
90 146
                ))->setMode($mode)
91
            };
92 146
            $imaginaryPart = match (true) {
93 146
                $partThis instanceof Fraction => match (true) {
94
                    $compareTo instanceof Fraction => self::normalizeObject($partThis, $mode),
95
                    default => self::normalizeObject($partThis->asDecimal(), $mode)
96
                },
97 146
                $partThis instanceof Decimal => self::normalizeObject($partThis, $mode)
98
            };
99
        }
100
101 266
        return [$realPart, $imaginaryPart];
102
103
    }
104
105
    /**
106
     * @param string $input
107
     * @param CalcMode|null $mode
108
     * @return ImmutableComplexNumber|ImmutableDecimal|ImmutableFraction
109
     * @throws IntegrityConstraint
110
     */
111 522
    protected static function stringSelector(string $input, ?CalcMode $mode): ImmutableComplexNumber|ImmutableDecimal|ImmutableFraction
112
    {
113
114 522
        $input = trim($input);
115 522
        if (str_contains($input, '/')) {
116 2
            $input = Numbers::makeFractionFromString(Numbers::IMMUTABLE_FRACTION, $input)->setMode($mode);
117 520
        } elseif (strrpos($input, '+') || strrpos($input, '-')) {
118
            $input = ComplexNumbers::make(ComplexNumbers::IMMUTABLE_COMPLEX, $input)->setMode($mode);
119
        } else {
120 520
            $input = Numbers::make(Numbers::IMMUTABLE, $input)->setMode($mode);
121
        }
122
123 522
        return $input;
124
125
    }
126
127
    /**
128
     * @param Fraction|Decimal|ComplexNumber $object
129
     * @param CalcMode|null $mode
130
     * @return ImmutableDecimal|ImmutableFraction|ImmutableComplexNumber
131
     * @throws IntegrityConstraint
132
     * @throws IncompatibleObjectState
133
     */
134 2983
    protected static function normalizeObject(
135
        Fraction|Decimal|ComplexNumber $object,
136
        ?CalcMode $mode
137
    ): ImmutableDecimal|ImmutableFraction|ImmutableComplexNumber
138
    {
139
        return match (true) {
140 2983
            $object instanceof Fraction => (new ImmutableFraction(
141 256
                new ImmutableDecimal(
142 256
                    $object->getNumerator()->getValue(NumberBase::Ten),
143 256
                    $object->getNumerator()->getScale(),
144 256
                    $object->getNumerator()->getBase()
145
                ),
146 256
                new ImmutableDecimal(
147 256
                    $object->getDenominator()->getValue(NumberBase::Ten),
148 256
                    $object->getDenominator()->getScale(),
149 256
                    $object->getDenominator()->getBase()
150
                ),
151 256
                $object->getBase()
152 256
            ))->setMode($mode),
153 2983
            $object instanceof Decimal => (new ImmutableDecimal(
154 2983
                $object->getValue(NumberBase::Ten),
155 2983
                $object->getScale(),
156 2983
                $object->getBase()
157 2983
            ))->setMode($mode),
158 242
            $object instanceof ComplexNumber => (new ImmutableComplexNumber(
159 242
                new ImmutableDecimal(
160 242
                    $object->getRealPart()->getValue(NumberBase::Ten),
161 242
                    $object->getRealPart()->getScale(),
162 242
                    $object->getRealPart()->getBase()
163
                ),
164 242
                new ImmutableDecimal(
165 242
                    $object->getImaginaryPart()->getValue(NumberBase::Ten),
166 242
                    $object->getImaginaryPart()->getScale(),
167 242
                    $object->getImaginaryPart()->getBase()
168
                ),
169 242
                $object->getScale()
170 242
            ))->setMode($mode),
171
            default => throw new IntegrityConstraint(
172
                'Cannot normalize provided object.',
173
                'When providing custom value classes, extend the abstract classes.'
174
            )
175
        };
176
    }
177
178
    /**
179
     * @param string|int|float|Decimal|Fraction|ComplexNumber $right
180
     * @return ImmutableFraction[]|ImmutableDecimal[]|ImmutableComplexNumber[]
181
     * @throws IntegrityConstraint
182
     */
183 2983
    protected function translateToObjects(string|int|float|Decimal|Fraction|ComplexNumber $right): array
184
    {
185 2983
        $normalizedLeft = self::normalizeObject($this, $this->getMode());
0 ignored issues
show
Bug introduced by
It seems like getMode() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

185
        $normalizedLeft = self::normalizeObject($this, $this->/** @scrutinizer ignore-call */ getMode());
Loading history...
186
187 2983
        $normalizedRight = match (gettype($right)) {
188 1719
            'integer', 'double' => (new ImmutableDecimal($right))->setMode($this->getMode()),
189 2851
            'object' => self::normalizeObject($right, $this->getMode()),
0 ignored issues
show
Bug introduced by
It seems like $right can also be of type double and integer and string; however, parameter $object of Samsara\Fermat\Core\Type...rait::normalizeObject() does only seem to accept Samsara\Fermat\Complex\T...mat\Core\Types\Fraction, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

189
            'object' => self::normalizeObject(/** @scrutinizer ignore-type */ $right, $this->getMode()),
Loading history...
190 522
            default => self::stringSelector($right, $this->getMode()),
191
        };
192
193 2983
        if ($normalizedLeft instanceof ImmutableDecimal && $normalizedRight instanceof ImmutableFraction) {
194 30
            $normalizedRight = $normalizedRight->asDecimal($this->getScale());
0 ignored issues
show
Bug introduced by
It seems like getScale() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

194
            $normalizedRight = $normalizedRight->asDecimal($this->/** @scrutinizer ignore-call */ getScale());
Loading history...
195
        }
196
197 2983
        return [$normalizedLeft, $normalizedRight];
198
    }
199
}