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, Debug)]
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}