mf2_runtime/functions/
number.rs1use mf2_model::Dir;
10
11use crate::error::FormatError;
12use crate::function::{FnContext, Function, Options};
13use crate::number::{self, Grouping, NumberSpec};
14use crate::sink::{ErrorSink, Sink, SubPartSink};
15use crate::value::Value;
16
17#[derive(Clone, Copy)]
19pub struct NumberFunction {
20 spec: NumberSpec,
21}
22
23impl NumberFunction {
24 pub(crate) const NUMBER: NumberFunction = NumberFunction {
25 spec: NumberSpec::NUMBER,
26 };
27 pub(crate) const INTEGER: NumberFunction = NumberFunction {
28 spec: NumberSpec::INTEGER,
29 };
30 pub(crate) const OFFSET: NumberFunction = NumberFunction {
31 spec: NumberSpec::OFFSET,
32 };
33}
34
35impl Function for NumberFunction {
36 fn resolve<'a>(
37 &self,
38 cx: &FnContext<'_>,
39 operand: Option<&Value<'a>>,
40 options: &Options<'_, 'a>,
41 errs: &mut dyn ErrorSink,
42 ) -> Option<Value<'a>> {
43 let n = number::resolve(self.spec, cx, operand, *options, errs)?;
44 if matches!(n.grouping(), Some(Grouping::Always | Grouping::Min2)) {
47 errs.error(FormatError::UnsupportedOperation);
48 }
49 Some(Value::Number(n))
50 }
51
52 fn formattable(&self, _cx: &FnContext<'_>, value: &Value<'_>) -> Result<(), FormatError> {
53 match value {
54 Value::Number(_) => Ok(()),
55 _ => Err(FormatError::MessageFunctionError),
56 }
57 }
58
59 fn format(&self, cx: &FnContext<'_>, value: &Value<'_>, out: &mut dyn Sink) {
60 if let Value::Number(n) = value {
61 n.write_display(cx, out);
62 }
63 }
64
65 fn format_parts(&self, cx: &FnContext<'_>, value: &Value<'_>, out: &mut dyn SubPartSink) {
66 if let Value::Number(n) = value {
67 n.display_parts(cx, out);
68 }
69 }
70
71 fn part_kind(&self) -> &'static str {
72 "number"
73 }
74
75 fn dir(&self, _cx: &FnContext<'_>, _value: &Value<'_>) -> Dir {
76 Dir::Ltr
78 }
79
80 fn selectable(&self, value: &Value<'_>) -> bool {
81 matches!(value, Value::Number(n) if n.selectable())
82 }
83
84 fn matches(
85 &self,
86 cx: &FnContext<'_>,
87 value: &Value<'_>,
88 key: &str,
89 errs: &mut dyn ErrorSink,
90 ) -> bool {
91 match value {
92 Value::Number(n) => number::matches(n, cx, key, errs),
93 _ => false,
94 }
95 }
96
97 fn better_than(&self, _cx: &FnContext<'_>, _value: &Value<'_>, key1: &str, key2: &str) -> bool {
98 number::better_than(key1, key2)
99 }
100}
101
102impl core::fmt::Debug for NumberFunction {
103 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
104 f.write_str("NumberFunction")
105 }
106}