|
1 | | -/// A dimension of measurement. These may be combined to form composite dimensions and measurements |
2 | | -public enum Quantity: String, Sendable { |
3 | | - // TODO: Consider changing away from enum for extensibility |
| 1 | +/// A dimension of measurement. These may be combined to form composite dimensions and measurements. |
| 2 | +/// |
| 3 | +/// `Quantity` is `RawRepresentable` rather than an enum so that callers can define their own |
| 4 | +/// dimensions without modifying this package. Add one with a static extension: |
| 5 | +/// |
| 6 | +/// ```swift |
| 7 | +/// extension Quantity { |
| 8 | +/// static let money = Quantity(rawValue: "Money") |
| 9 | +/// } |
| 10 | +/// ``` |
| 11 | +/// |
| 12 | +/// Equality and hashing are based on `rawValue`, so each distinct dimension needs a unique |
| 13 | +/// raw string. Because the namespace is global across every module that links this package, |
| 14 | +/// two modules that independently pick the same raw value are treated as the *same* dimension |
| 15 | +/// and silently cancel against one another. Prefix custom raw values to avoid collisions — |
| 16 | +/// e.g. `"Acme.Money"` rather than `"Money"`. |
| 17 | +public struct Quantity: RawRepresentable, Hashable, Sendable { |
| 18 | + public let rawValue: String |
| 19 | + |
| 20 | + public init(rawValue: String) { |
| 21 | + self.rawValue = rawValue |
| 22 | + } |
4 | 23 |
|
5 | 24 | // Base ISQ quantities: https://en.wikipedia.org/wiki/International_System_of_Quantities#Base_quantities |
6 | | - case Amount |
7 | | - case Current |
8 | | - case Length |
9 | | - case Mass |
10 | | - case Temperature |
11 | | - case Time |
12 | | - case LuminousIntensity |
| 25 | + public static let amount = Quantity(rawValue: "Amount") |
| 26 | + public static let current = Quantity(rawValue: "Current") |
| 27 | + public static let length = Quantity(rawValue: "Length") |
| 28 | + public static let mass = Quantity(rawValue: "Mass") |
| 29 | + public static let temperature = Quantity(rawValue: "Temperature") |
| 30 | + public static let time = Quantity(rawValue: "Time") |
| 31 | + public static let luminousIntensity = Quantity(rawValue: "LuminousIntensity") |
13 | 32 |
|
14 | 33 | // Extended SI Units: https://en.wikipedia.org/wiki/Non-SI_units_mentioned_in_the_SI |
15 | | - case Angle |
16 | | - case Data |
| 34 | + public static let angle = Quantity(rawValue: "Angle") |
| 35 | + public static let data = Quantity(rawValue: "Data") |
| 36 | +} |
| 37 | + |
| 38 | +// MARK: - Deprecated PascalCase aliases |
| 39 | + |
| 40 | +// The previous `enum Quantity` spelled its cases in PascalCase. These aliases keep existing |
| 41 | +// call sites compiling against the renamed lowerCamelCase properties (Swift API Design |
| 42 | +// Guidelines) and can be removed in a future major release. |
| 43 | +public extension Quantity { |
| 44 | + @available(*, deprecated, renamed: "amount") |
| 45 | + static let Amount = Quantity.amount |
| 46 | + @available(*, deprecated, renamed: "current") |
| 47 | + static let Current = Quantity.current |
| 48 | + @available(*, deprecated, renamed: "length") |
| 49 | + static let Length = Quantity.length |
| 50 | + @available(*, deprecated, renamed: "mass") |
| 51 | + static let Mass = Quantity.mass |
| 52 | + @available(*, deprecated, renamed: "temperature") |
| 53 | + static let Temperature = Quantity.temperature |
| 54 | + @available(*, deprecated, renamed: "time") |
| 55 | + static let Time = Quantity.time |
| 56 | + @available(*, deprecated, renamed: "luminousIntensity") |
| 57 | + static let LuminousIntensity = Quantity.luminousIntensity |
| 58 | + @available(*, deprecated, renamed: "angle") |
| 59 | + static let Angle = Quantity.angle |
| 60 | + @available(*, deprecated, renamed: "data") |
| 61 | + static let Data = Quantity.data |
| 62 | +} |
| 63 | + |
| 64 | +// MARK: - CustomStringConvertible |
| 65 | + |
| 66 | +extension Quantity: CustomStringConvertible { |
| 67 | + // Preserve the enum's behavior: interpolating a Quantity yields its raw value |
| 68 | + // (e.g. "Length"), not the synthesized struct description. |
| 69 | + public var description: String { rawValue } |
17 | 70 | } |
0 commit comments