Skip to main content

prefixmap/iri/
visitor.rs

1use crate::IriRef;
2use serde::Deserialize;
3use serde::de::Visitor;
4use std::str::FromStr;
5
6struct IriRefVisitor;
7
8impl<'de> Visitor<'de> for IriRefVisitor {
9    type Value = IriRef;
10
11    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
12        formatter.write_str("a valid IRI or a prefixed name")
13    }
14
15    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
16    where
17        E: serde::de::Error,
18    {
19        match IriRef::from_str(v) {
20            Ok(iri_ref) => Ok(iri_ref),
21            Err(_) => {
22                // Try to parse as prefixed name
23                let parts: Vec<&str> = v.splitn(2, ':').collect();
24                if parts.len() == 2 {
25                    let prefix = parts[0].to_string();
26                    let local = parts[1].to_string();
27                    Ok(IriRef::Prefixed { prefix, local })
28                } else {
29                    Err(E::custom(format!("Invalid IRI or prefixed name: {}", v)))
30                }
31            },
32        }
33    }
34}
35
36impl<'de> Deserialize<'de> for IriRef {
37    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
38    where
39        D: serde::Deserializer<'de>,
40    {
41        deserializer.deserialize_str(IriRefVisitor)
42    }
43}