Skip to main content

mf2_runtime/functions/
string.rs

1//! `:string` (`functions/string.md`): formats its operand's string form and
2//! selects by asking whether the operand is canonically equivalent to the
3//! (NFC) key, which the catalog's own map decides (`plan/01` ยง4.3). No
4//! options; direction unknown.
5
6use crate::error::FormatError;
7use crate::function::{FnContext, Function, Options};
8use crate::number::equals;
9use crate::sink::{ErrorSink, Sink};
10use crate::unannotated;
11use crate::value::Value;
12
13/// The `:string` handler.
14#[derive(Clone, Copy, Default, Debug)]
15pub struct StringFunction;
16
17impl Function for StringFunction {
18    fn resolve<'a>(
19        &self,
20        cx: &FnContext<'_>,
21        operand: Option<&Value<'a>>,
22        _options: &Options<'_, 'a>,
23        errs: &mut dyn ErrorSink,
24    ) -> Option<Value<'a>> {
25        // Any literal, and any value with a string conversion; the rest is a
26        // Bad Operand.
27        let value = operand.and_then(Value::try_copy);
28        match value {
29            Some(v) if unannotated::formattable(&v, cx.host()).is_ok() => Some(v),
30            _ => {
31                errs.error(FormatError::BadOperand);
32                None
33            }
34        }
35    }
36
37    fn format(&self, cx: &FnContext<'_>, value: &Value<'_>, out: &mut dyn Sink) {
38        unannotated::format(value, cx.host(), out);
39    }
40
41    fn selectable(&self, _value: &Value<'_>) -> bool {
42        true
43    }
44
45    fn matches(
46        &self,
47        cx: &FnContext<'_>,
48        value: &Value<'_>,
49        key: &str,
50        _errs: &mut dyn ErrorSink,
51    ) -> bool {
52        match value.as_str() {
53            // A variant key is the catalog's, so inside the map's domain.
54            Some(s) => crate::nfc::equivalent(cx.catalog.nfc_map(), s, key),
55            // A number's string form is ASCII, so already NFC.
56            None => equals(key, |out| unannotated::format(value, cx.host(), out)),
57        }
58    }
59}