Skip to main content

mf2_runtime/functions/
string.rs

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