-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathCurrency.php
115 lines (99 loc) · 2.62 KB
/
Currency.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<?php
namespace ICanBoogie\CLDR\Numbers;
use ICanBoogie\CLDR\Core\Locale;
use ICanBoogie\CLDR\Core\Localizable;
/**
* Representation of a currency.
*
* @link https://www.unicode.org/reports/tr35/tr35-72/tr35-numbers.html#Currencies
*
* @implements Localizable<Currency, CurrencyLocalized>
*/
final class Currency implements Localizable
{
/**
* Whether a currency code is defined.
*
* @param string $code
* A currency code; for example, EUR.
*/
public static function is_defined(string $code): bool
{
return in_array($code, CurrencyData::CODES);
}
/**
* @param string $code
* A currency code; for example, EUR.
*
* @throws CurrencyNotDefined
*/
public static function assert_is_defined(string $code): void
{
self::is_defined($code)
or throw new CurrencyNotDefined($code);
}
/**
* Returns a {@see CurrencyCode} of the specified code.
*
* @param string $code
* A currency code; for example, EUR.
*
* @throws CurrencyNotDefined
*/
public static function of(string $code): self
{
static $instances;
self::assert_is_defined($code);
return $instances[$code] ??= new self($code, self::fraction_for($code));
}
/**
* Returns the {@see Fraction} for the specified currency code.
*
* @param string $code
* * A currency code; for example, EUR.
*/
private static function fraction_for(string $code): Fraction
{
static $default_fraction;
$data = CurrencyData::FRACTIONS[$code] ?? null;
if (!$data) {
return $default_fraction ??= self::fraction_for(CurrencyData::FRACTIONS_FALLBACK);
}
return Fraction::from($data);
}
/**
* @param string $code
* A currency code; for example, EUR.
*/
private function __construct(
public readonly string $code,
public readonly Fraction $fraction,
) {
}
/**
* Returns the {@see $code} of the currency.
*/
public function __toString(): string
{
return $this->code;
}
public function __serialize(): array
{
return [ 'code' => $this->code ];
}
/**
* @param array{ code: string } $data
*/
public function __unserialize(array $data): void
{
$this->code = $data['code'];
$this->fraction = self::fraction_for($this->code);
}
/**
* Returns a localized currency.
*/
public function localized(Locale $locale): CurrencyLocalized
{
return new CurrencyLocalized($this, $locale);
}
}