resource_path/third_party/
der.rs1use std::{fmt::Formatter, str::FromStr};
2
3use serde::{
4 de::{Error, MapAccess, Visitor},
5 Deserialize, Deserializer,
6};
7
8use crate::ResourcePath;
9
10struct PathVisitor {}
11
12impl<'de> Deserialize<'de> for ResourcePath {
13 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
14 where
15 D: Deserializer<'de>,
16 {
17 let out = deserializer.deserialize_any(PathVisitor {})?;
18 Ok(out)
19 }
20 fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
21 where
22 D: Deserializer<'de>,
23 {
24 *place = deserializer.deserialize_any(PathVisitor {})?;
25 Ok(())
26 }
27}
28
29impl<'de> Visitor<'de> for PathVisitor {
30 type Value = ResourcePath;
31
32 fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
33 formatter.write_str("Except a `ResourcePath` object or a `Url` string.")
34 }
35
36 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
37 where
38 E: Error,
39 {
40 match ResourcePath::from_str(v) {
41 Ok(o) => Ok(o),
42 Err(e) => Err(Error::custom(e.to_string())),
43 }
44 }
45
46 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
47 where
48 A: MapAccess<'de>,
49 {
50 let mut network = None;
51 let mut relative = None;
52 while let Some(key) = map.next_key::<&str>()? {
53 match key {
54 "network" | "remote" => {
55 network = Some(map.next_value()?);
56 }
57 "relative" | "local" => {
58 relative = Some(map.next_value()?);
59 }
60 _ => {}
61 }
62 }
63 match (network, relative) {
64 (Some(network), Some(relative)) => Ok(ResourcePath { remote: network, local: relative }),
65 (_, None) => Err(Error::missing_field("relative")),
66 _ => Err(Error::missing_field("network")),
67 }
68 }
69}