Skip to main content

sofie_core/
parsed.rs

1use std::fmt;
2
3use serde::de::{self, Visitor};
4
5/// Through the parser, so a request cannot build the value without the check; a refusal is
6/// written in its alternate form, as the field being read already names the value.
7pub fn deserialize_parsed<'de, V, M: fmt::Display, D: serde::Deserializer<'de>>(
8    deserializer: D,
9    expected: &'static str,
10    parse: fn(&str) -> Result<V, M>,
11) -> Result<V, D::Error> {
12    deserializer.deserialize_str(Parsed { expected, parse })
13}
14
15struct Parsed<V, M> {
16    expected: &'static str,
17    parse: fn(&str) -> Result<V, M>,
18}
19
20impl<V, M: fmt::Display> Visitor<'_> for Parsed<V, M> {
21    type Value = V;
22
23    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
24        formatter.write_str(self.expected)
25    }
26
27    fn visit_str<E: de::Error>(self, text: &str) -> Result<V, E> {
28        (self.parse)(text).map_err(|refusal| E::custom(format_args!("{refusal:#}")))
29    }
30}