@@ -24,13 +24,13 @@ abstract class AbstractConverter implements \Stringable
2424 set(mixed $ value ) => $ this ->value = BigDecimal::of ($ value );
2525 }
2626
27- public string $ baseUnit ;
27+ public protected(set) string $ unit ;
2828
29- abstract public string $ atomUnit {
29+ abstract public protected(set) string $ atomUnit {
3030 get;
3131 }
3232
33- abstract public string $ defaultUnit {
33+ abstract public protected(set) string $ defaultUnit {
3434 get;
3535 }
3636
@@ -51,6 +51,18 @@ abstract class AbstractConverter implements \Stringable
5151 }
5252 }
5353
54+ public string $ baseUnit {
55+ get {
56+ foreach ($ this ->availableUnitExchanges as $ unit => $ rate ) {
57+ if (BigDecimal::of ($ rate )->isEqualTo (1 )) {
58+ return $ unit ;
59+ }
60+ }
61+
62+ throw new \RuntimeException ('No base unit found in available unit exchanges. ' );
63+ }
64+ }
65+
5466 protected ?array $ availableUnits = null ;
5567
5668 public ?\Closure $ unitNormalizer = null ;
@@ -114,20 +126,20 @@ public function withParse(
114126
115127 $ new = $ new ->withValue ($ atomValue );
116128
117- $ asUnit ??= $ this ->baseUnit ;
129+ $ asUnit ??= $ this ->unit ;
118130
119- if ($ asUnit && $ asUnit !== $ new ->baseUnit ) {
131+ if ($ asUnit && $ asUnit !== $ new ->unit ) {
120132 $ asUnit = $ this ->normalizeUnit ($ asUnit );
121133 $ new = $ new ->convertTo ($ asUnit , $ scale , $ roundingMode );
122134 }
123135
124136 return $ new ;
125137 }
126138
127- public function __construct (mixed $ value = 0 , ?string $ baseUnit = null )
139+ public function __construct (mixed $ value = 0 , ?string $ unit = null )
128140 {
129141 $ this ->value = $ value ;
130- $ this ->baseUnit = $ baseUnit ?? $ this ->defaultUnit ;
142+ $ this ->unit = $ unit ?? $ this ->defaultUnit ;
131143 }
132144
133145 public function withAvailableUnits (?array $ units ): static
@@ -176,17 +188,17 @@ public function convertTo(
176188 ): static {
177189 $ toUnit = $ this ->normalizeUnit ($ toUnit );
178190
179- if ($ toUnit === $ this ->baseUnit ) {
191+ if ($ toUnit === $ this ->unit ) {
180192 return $ this ;
181193 }
182194
183195 $ new = clone $ this ;
184196
185197 if (!$ new ->value ->isZero ()) {
186- $ new ->value = $ this ->convertValue ($ new ->value , $ new ->baseUnit , $ toUnit , $ scale , $ roundingMode );
198+ $ new ->value = $ this ->convertValue ($ new ->value , $ new ->unit , $ toUnit , $ scale , $ roundingMode );
187199 }
188200
189- $ new ->baseUnit = $ toUnit ;
201+ $ new ->unit = $ toUnit ;
190202
191203 return $ new ;
192204 }
@@ -228,28 +240,28 @@ public function withValue(
228240 ): static {
229241 $ new = clone $ this ;
230242 $ new ->value = $ value ;
231- $ new ->baseUnit = $ fromUnit ? $ new ->normalizeUnit ($ fromUnit ) : $ this ->baseUnit ;
243+ $ new ->unit = $ fromUnit ? $ new ->normalizeUnit ($ fromUnit ) : $ this ->unit ;
232244
233- if ($ new ->baseUnit !== $ this ->baseUnit ) {
234- $ new = $ new ->convertTo ($ this ->baseUnit , $ scale , $ roundingMode );
245+ if ($ new ->unit !== $ this ->unit ) {
246+ $ new = $ new ->convertTo ($ this ->unit , $ scale , $ roundingMode );
235247 }
236248
237249 return $ new ;
238250 }
239251
240- public function withBaseUnit (string $ unit ): static
252+ public function withUnit (string $ unit ): static
241253 {
242254 $ new = clone $ this ;
243- $ new ->baseUnit = $ this ->normalizeUnit ($ unit );
255+ $ new ->unit = $ this ->normalizeUnit ($ unit );
244256
245257 return $ new ;
246258 }
247259
248- public function with (mixed $ value , ?string $ baseUnit = null ): static
260+ public function with (mixed $ value , ?string $ unit = null ): static
249261 {
250262 $ new = clone $ this ;
251263 $ new ->value = $ value ;
252- $ new ->baseUnit = $ baseUnit ? $ this ->normalizeUnit ($ baseUnit ) : $ this ->baseUnit ;
264+ $ new ->unit = $ unit ? $ this ->normalizeUnit ($ unit ) : $ this ->unit ;
253265
254266 return $ new ;
255267 }
@@ -285,7 +297,7 @@ public function format(
285297 $ value = $ value ->stripTrailingZeros ();
286298 }
287299
288- $ unit ??= $ this ->baseUnit ;
300+ $ unit ??= $ this ->unit ;
289301 $ suffix ??= $ unit ;
290302
291303 if ($ suffix instanceof \Closure) {
@@ -314,7 +326,7 @@ public function isNegative(): bool
314326 /**
315327 * @param string $unit
316328 *
317- * @return array{ static, static }
329+ * @return array{ static, static } A tuple with [extracted, remainder]
318330 */
319331 public function withExtract (string $ unit ): array
320332 {
@@ -325,7 +337,7 @@ public function withExtract(string $unit): array
325337
326338 protected function extract (string $ unit ): static
327339 {
328- $ rate = $ this ->with (1 , $ unit )->convertTo ($ this ->baseUnit )->value ;
340+ $ rate = $ this ->with (1 , $ unit )->convertTo ($ this ->unit )->value ;
329341
330342 /** @var BigDecimal $part */
331343 $ part = $ this ->value ->dividedBy ($ rate , 0 , RoundingMode::DOWN );
@@ -416,14 +428,16 @@ public function getUnitExchangeRate(string $unit): ?BigNumber
416428
417429 /**
418430 * @param array<BigNumber|float|int> $units
431+ * @param string $atomUnit
419432 * @param string $defaultUnit
420433 *
421434 * @return $this
422435 */
423- public function withUnitExchanges (array $ units , string $ defaultUnit ): static
436+ public function withUnitExchanges (array $ units , string $ atomUnit , string $ defaultUnit ): static
424437 {
425438 $ new = clone $ this ;
426439 $ new ->unitExchanges = $ units ;
440+ $ new ->atomUnit = $ atomUnit ;
427441 $ new ->defaultUnit = $ defaultUnit ;
428442
429443 return $ new ;
@@ -573,6 +587,22 @@ public static function unitConstants(): array
573587 return $ returnConstants ;
574588 }
575589
590+ public function withDefaultUnit (string $ defaultUnit ): static
591+ {
592+ $ new = clone $ this ;
593+ $ new ->defaultUnit = $ defaultUnit ;
594+
595+ return $ new ;
596+ }
597+
598+ public function withAtomUnit (string $ atomUnit ): static
599+ {
600+ $ new = clone $ this ;
601+ $ new ->atomUnit = $ atomUnit ;
602+
603+ return $ new ;
604+ }
605+
576606 public function __toString (): string
577607 {
578608 return (string ) $ this ->value ->toBigDecimal ()->stripTrailingZeros ();
0 commit comments