1use std::fmt;
2
3use serde::de::{self, Visitor};
4
5pub 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}