Skip to main content

mf2_runtime/number/
measure.rs

1//! A number with a currency or a unit (`plans/03-runtime.md` §2.7): what
2//! `:currency` and `:unit` (`mf2-fn-number`) resolve to. The runtime only
3//! carries it — as a numeric operand it is its number.
4
5use super::Number;
6
7/// A number with a currency or a unit, and the options its function added.
8#[derive(Clone)]
9#[non_exhaustive]
10pub struct Measure<'a> {
11    /// The number, with its resolved numeric options.
12    pub number: Number,
13    /// The currency or the unit.
14    pub unit: MeasureUnit<'a>,
15    /// The resolving crate's own encoding of the options it adds
16    /// (`currencyDisplay`, `currencySign`, `fractionDigits`, `unitDisplay`),
17    /// inherited by a later `:currency` / `:unit` that takes this value as
18    /// its operand. The runtime never reads it.
19    pub flags: u32,
20}
21
22impl<'a> Measure<'a> {
23    /// A measure of `number` in `unit`.
24    pub fn new(number: Number, unit: MeasureUnit<'a>, flags: u32) -> Self {
25        Measure {
26            number,
27            unit,
28            flags,
29        }
30    }
31}
32
33/// What a [`Measure`] measures.
34#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
35pub enum MeasureUnit<'a> {
36    /// A currency: a well-formed code (`currency_code = 3ALPHA`), upper-cased.
37    Currency([u8; 3]),
38    /// A unit: a well-formed Unicode unit identifier, as written.
39    Unit(&'a str),
40}
41
42impl MeasureUnit<'_> {
43    /// The currency code or the unit identifier, as text.
44    pub fn as_str(&self) -> &str {
45        match self {
46            MeasureUnit::Currency(c) => core::str::from_utf8(c).unwrap_or(""),
47            MeasureUnit::Unit(u) => u,
48        }
49    }
50}