ipld_nostd/ipld/serde/
extract_links.rs

1use {
2	crate::cid::CidGeneric,
3	alloc::{vec, vec::Vec},
4	core::fmt,
5	serde::{de, Deserialize},
6	serde_bytes::ByteBuf,
7};
8
9/// Extract links from an `ipld_serde_dag*` codec.
10#[derive(Debug)]
11pub struct ExtractLinks<const S: usize> {
12	links: Vec<CidGeneric<S>>,
13}
14
15impl<const S: usize> ExtractLinks<S> {
16	/// Get the extracted links (CIDs).
17	pub fn into_vec(self) -> Vec<CidGeneric<S>> {
18		self.links
19	}
20}
21
22impl<'de, const S: usize> de::Visitor<'de> for ExtractLinks<S> {
23	type Value = Vec<CidGeneric<S>>;
24
25	fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
26		formatter.write_str("anything at all")
27	}
28
29	#[inline]
30	fn visit_bool<E>(self, _value: bool) -> Result<Self::Value, E> {
31		Ok(Vec::new())
32	}
33
34	#[inline]
35	fn visit_i64<E>(self, _value: i64) -> Result<Self::Value, E> {
36		Ok(Vec::new())
37	}
38
39	#[inline]
40	fn visit_i128<E>(self, _value: i128) -> Result<Self::Value, E> {
41		Ok(Vec::new())
42	}
43
44	#[inline]
45	fn visit_u64<E>(self, _value: u64) -> Result<Self::Value, E> {
46		Ok(Vec::new())
47	}
48
49	#[inline]
50	fn visit_u128<E>(self, _value: u128) -> Result<Self::Value, E> {
51		Ok(Vec::new())
52	}
53
54	#[inline]
55	fn visit_f64<E>(self, _value: f64) -> Result<Self::Value, E> {
56		Ok(Vec::new())
57	}
58
59	#[inline]
60	fn visit_str<E>(self, _value: &str) -> Result<Self::Value, E>
61	where
62		E: de::Error,
63	{
64		Ok(Vec::new())
65	}
66
67	#[inline]
68	fn visit_none<E>(self) -> Result<Self::Value, E> {
69		Ok(Vec::new())
70	}
71
72	#[inline]
73	fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
74	where
75		D: de::Deserializer<'de>,
76	{
77		Ok(Self::deserialize(deserializer)?.links)
78	}
79
80	#[inline]
81	fn visit_newtype_struct<D>(
82		self,
83		deserializer: D,
84	) -> Result<Self::Value, D::Error>
85	where
86		D: de::Deserializer<'de>,
87	{
88		// No DAG-* format has the idea of a newtyp struct. Therefore when visiting
89		// a newtype struct, we can be sure that it's from deserializing a CID.
90		let bytes = ByteBuf::deserialize(deserializer)?;
91		let cid = CidGeneric::try_from(&bytes[..])
92			.map_err(|_| de::Error::custom("Cannot decode CID"))?;
93		Ok(vec![cid])
94	}
95
96	#[inline]
97	fn visit_unit<E>(self) -> Result<Self::Value, E> {
98		Ok(Vec::new())
99	}
100
101	#[inline]
102	fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
103	where
104		A: de::SeqAccess<'de>,
105	{
106		let mut links = Vec::new();
107		while let Some(mut maybe_links) = seq.next_element::<Self>()? {
108			links.append(&mut maybe_links.links)
109		}
110		Ok(links)
111	}
112
113	#[inline]
114	fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
115	where
116		A: de::MapAccess<'de>,
117	{
118		let mut links = Vec::new();
119		while let Some((_, mut maybe_links)) = map.next_entry::<Self, Self>()? {
120			links.append(&mut maybe_links.links)
121		}
122		Ok(links)
123	}
124
125	#[inline]
126	fn visit_bytes<E>(self, _value: &[u8]) -> Result<Self::Value, E>
127	where
128		E: de::Error,
129	{
130		Ok(Vec::new())
131	}
132
133	fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
134	where
135		A: de::EnumAccess<'de>,
136	{
137		use serde::de::VariantAccess;
138		data.variant::<Self>()?.1.newtype_variant()
139	}
140}
141
142impl<'de, const S: usize> de::Deserialize<'de> for ExtractLinks<S> {
143	#[inline]
144	fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
145	where
146		D: de::Deserializer<'de>,
147	{
148		let links = deserializer.deserialize_any(Self { links: Vec::new() })?;
149		Ok(Self { links })
150	}
151}