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)) {
48 errs.error(FormatError::UnsupportedOperation);
49 }
50 Some(Value::Number(n))
51 }
52
53 fn formattable(&self, _cx: &FnContext<'_>, value: &Value<'_>) -> Result<(), FormatError> {
54 match value {
55 Value::Number(_) => Ok(()),
56 _ => Err(FormatError::MessageFunctionError),
57 }
58 }
59
60 fn format(&self, cx: &FnContext<'_>, value: &Value<'_>, out: &mut dyn Sink) {
61 if let Value::Number(n) = value {
62 n.write_display(cx, out);
63 }
64 }
65
66 fn format_parts(&self, cx: &FnContext<'_>, value: &Value<'_>, out: &mut dyn SubPartSink) {
67 if let Value::Number(n) = value {
68 n.display_parts(cx, out);
69 }
70 }
71
72 fn part_kind(&self) -> &'static str {
73 "number"
74 }
75
76 fn dir(&self, _cx: &FnContext<'_>, _value: &Value<'_>) -> Dir {
77 Dir::Ltr
79 }
80
81 fn selectable(&self, value: &Value<'_>) -> bool {
82 matches!(value, Value::Number(n) if n.selectable())
83 }
84
85 fn matches(
86 &self,
87 cx: &FnContext<'_>,
88 value: &Value<'_>,
89 key: &str,
90 errs: &mut dyn ErrorSink,
91 ) -> bool {
92 match value {
93 Value::Number(n) => number::matches(n, cx, key, errs),
94 _ => false,
95 }
96 }
97
98 fn better_than(&self, _cx: &FnContext<'_>, _value: &Value<'_>, key1: &str, key2: &str) -> bool {
99 number::better_than(key1, key2)
100 }
101}
102
103impl core::fmt::Debug for NumberFunction {
104 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
105 f.write_str("NumberFunction")
106 }
107}