krates/cm/
de.rs

1use super::*;
2use serde::de::{Deserialize, Deserializer, Error, Visitor};
3type Key<'de> = std::borrow::Cow<'de, str>;
4
5macro_rules! tri {
6    ($res:expr) => {
7        match $res {
8            Ok(r) => r,
9            Err(err) => return Err(err),
10        }
11    };
12}
13
14impl<'de> Deserialize<'de> for PackageId {
15    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
16    where
17        D: Deserializer<'de>,
18    {
19        Ok(Self {
20            repr: tri!(String::deserialize(deserializer)),
21        })
22    }
23}
24
25macro_rules! map {
26    ($kind:ty, $map:ident, $func:block) => {
27        impl<'de> Deserialize<'de> for $kind {
28            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
29            where
30                D: Deserializer<'de>,
31            {
32                struct V;
33
34                impl<'de> Visitor<'de> for V {
35                    type Value = $kind;
36
37                    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
38                        formatter.write_str(concat!("an ", stringify!($kind)))
39                    }
40
41                    fn visit_map<A>(self, mut $map: A) -> Result<Self::Value, A::Error>
42                    where
43                        A: serde::de::MapAccess<'de>,
44                    {
45                        $func
46                    }
47                }
48
49                deserializer.deserialize_map(V)
50            }
51        }
52    };
53}
54
55macro_rules! parse {
56    ($kind:ty) => {
57        impl<'de> Deserialize<'de> for $kind {
58            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
59            where
60                D: Deserializer<'de>,
61            {
62                let s = tri!(std::borrow::Cow::<'de, str>::deserialize(deserializer));
63                s.parse().map_err(|err| Error::custom(err))
64            }
65        }
66    };
67}
68
69macro_rules! required {
70    ($name:ident) => {
71        if let Some(v) = $name {
72            v
73        } else {
74            return Err(Error::missing_field(stringify!($name)));
75        }
76    };
77}
78
79map!(Metadata, map, {
80    let mut packages = None;
81    let mut workspace_members = None;
82    let mut workspace_default_members = None;
83    let mut resolve = None;
84    let mut workspace_root = None;
85    let mut target_directory = None;
86    let mut workspace_metadata = serde_json::Value::Null;
87    let mut version = 0;
88
89    while let Some(key) = tri!(map.next_key::<Key<'de>>()) {
90        match key.as_ref() {
91            "packages" => packages = Some(tri!(map.next_value())),
92            "workspace_members" => workspace_members = Some(tri!(map.next_value())),
93            "workspace_default_members" => workspace_default_members = Some(tri!(map.next_value())),
94            "resolve" => resolve = Some(tri!(map.next_value())),
95            "workspace_root" => workspace_root = Some(tri!(map.next_value())),
96            "target_directory" => target_directory = Some(tri!(map.next_value())),
97            "metadata" => workspace_metadata = tri!(map.next_value()),
98            "version" => version = tri!(map.next_value()),
99            _ => {
100                tri!(map.next_value::<Ignore>());
101            }
102        }
103    }
104
105    Ok(Metadata {
106        packages: required!(packages),
107        workspace_members: required!(workspace_members),
108        workspace_default_members: WorkspaceDefaultMembers(workspace_default_members),
109        resolve,
110        workspace_root: required!(workspace_root),
111        target_directory: required!(target_directory),
112        workspace_metadata,
113        version,
114    })
115});
116
117map!(Resolve, map, {
118    let mut nodes = None;
119    let mut root = None;
120
121    while let Some(key) = tri!(map.next_key::<Key<'de>>()) {
122        match key.as_ref() {
123            "nodes" => nodes = Some(tri!(map.next_value())),
124            "root" => root = Some(tri!(map.next_value())),
125            _ => {
126                tri!(map.next_value::<Ignore>());
127            }
128        }
129    }
130
131    Ok(Resolve {
132        nodes: required!(nodes),
133        root: required!(root),
134    })
135});
136
137map!(Node, map, {
138    let mut id = None;
139    let mut deps = Vec::new();
140    let mut dependencies = None;
141    let mut features = Vec::new();
142
143    while let Some(key) = tri!(map.next_key::<Key<'de>>()) {
144        match key.as_ref() {
145            "id" => id = Some(tri!(map.next_value())),
146            "deps" => deps = tri!(map.next_value()),
147            "dependencies" => dependencies = Some(tri!(map.next_value())),
148            "features" => features = tri!(map.next_value()),
149            _ => {
150                tri!(map.next_value::<Ignore>());
151            }
152        }
153    }
154
155    Ok(Node {
156        id: required!(id),
157        deps,
158        dependencies: required!(dependencies),
159        features,
160    })
161});
162
163map!(NodeDep, map, {
164    let mut name = None;
165    let mut pkg = None;
166    let mut dep_kinds = Vec::new();
167
168    while let Some(key) = tri!(map.next_key::<Key<'de>>()) {
169        match key.as_ref() {
170            "name" => name = Some(tri!(map.next_value())),
171            "pkg" => pkg = Some(tri!(map.next_value())),
172            "dep_kinds" => dep_kinds = tri!(map.next_value()),
173            _ => {
174                tri!(map.next_value::<Ignore>());
175            }
176        }
177    }
178
179    Ok(NodeDep {
180        name: required!(name),
181        pkg: required!(pkg),
182        dep_kinds,
183    })
184});
185
186map!(DepKindInfo, map, {
187    let mut kind = DependencyKind::Normal;
188    let mut target = None;
189
190    while let Some(key) = tri!(map.next_key::<Key<'de>>()) {
191        match key.as_ref() {
192            "kind" => kind = tri!(map.next_value()),
193            "target" => target = tri!(map.next_value()),
194            _ => {
195                tri!(map.next_value::<Ignore>());
196            }
197        }
198    }
199
200    Ok(DepKindInfo { kind, target })
201});
202
203impl<'de> Deserialize<'de> for DependencyKind {
204    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
205    where
206        D: Deserializer<'de>,
207    {
208        let kind = tri!(Option::<std::borrow::Cow<'de, str>>::deserialize(
209            deserializer
210        ));
211        if let Some(kind) = kind {
212            Ok(match kind.as_ref() {
213                "normal" => Self::Normal,
214                "dev" => Self::Development,
215                "build" => Self::Build,
216                unknown => {
217                    return Err(Error::unknown_variant(unknown, &["normal", "dev", "build"]));
218                }
219            })
220        } else {
221            Ok(Self::Normal)
222        }
223    }
224}
225
226map!(Dependency, map, {
227    let mut name = None;
228    let mut source = None;
229    let mut req = None;
230    let mut kind = DependencyKind::Normal;
231    let mut optional = None;
232    let mut uses_default_features = None;
233    let mut features = None;
234    let mut target = None;
235    let mut rename = None;
236    let mut registry = None;
237    let mut path = None;
238
239    while let Some(key) = tri!(map.next_key::<Key<'de>>()) {
240        match key.as_ref() {
241            "name" => name = Some(tri!(map.next_value())),
242            "source" => source = tri!(map.next_value()),
243            "req" => req = Some(tri!(map.next_value())),
244            "kind" => kind = tri!(map.next_value()),
245            "optional" => optional = Some(tri!(map.next_value())),
246            "uses_default_features" => uses_default_features = Some(tri!(map.next_value())),
247            "features" => features = Some(tri!(map.next_value())),
248            "target" => target = tri!(map.next_value()),
249            "rename" => rename = tri!(map.next_value()),
250            "registry" => registry = tri!(map.next_value()),
251            "path" => path = tri!(map.next_value()),
252            _ => {
253                tri!(map.next_value::<Ignore>());
254            }
255        }
256    }
257
258    Ok(Dependency {
259        name: required!(name),
260        source,
261        req: required!(req),
262        kind,
263        optional: required!(optional),
264        uses_default_features: required!(uses_default_features),
265        features: required!(features),
266        target,
267        rename,
268        registry,
269        path,
270    })
271});
272
273parse!(TargetKind);
274parse!(CrateType);
275parse!(Edition);
276
277map!(Package, map, {
278    let mut name = None;
279    let mut version = None;
280    let mut authors = Vec::new();
281    let mut id = None;
282    let mut source = None;
283    let mut description = None;
284    let mut dependencies = None;
285    let mut license = None;
286    let mut license_file = None;
287    let mut targets = None;
288    let mut features = None;
289    let mut manifest_path = None;
290    let mut categories = Vec::new();
291    let mut keywords = Vec::new();
292    let mut readme = None;
293    let mut repository = None;
294    let mut homepage = None;
295    let mut documentation = None;
296    let mut edition = Edition::default();
297    let mut metadata = serde_json::Value::Null;
298    let mut links = None;
299    let mut publish = None;
300    let mut default_run = None;
301    let mut rust_version = None;
302
303    while let Some(key) = tri!(map.next_key::<Key<'de>>()) {
304        match key.as_ref() {
305            "name" => name = Some(tri!(map.next_value())),
306            "version" => version = Some(tri!(map.next_value())),
307            "authors" => authors = tri!(map.next_value()),
308            "id" => id = Some(tri!(map.next_value())),
309            "source" => source = tri!(map.next_value()),
310            "description" => description = tri!(map.next_value()),
311            "dependencies" => dependencies = Some(tri!(map.next_value())),
312            "license" => license = tri!(map.next_value()),
313            "license_file" => license_file = tri!(map.next_value()),
314            "targets" => targets = Some(tri!(map.next_value())),
315            "features" => features = Some(tri!(map.next_value())),
316            "manifest_path" => manifest_path = Some(tri!(map.next_value())),
317            "categories" => categories = tri!(map.next_value()),
318            "keywords" => keywords = tri!(map.next_value()),
319            "readme" => readme = tri!(map.next_value()),
320            "repository" => repository = tri!(map.next_value()),
321            "homepage" => homepage = tri!(map.next_value()),
322            "documentation" => documentation = tri!(map.next_value()),
323            "edition" => edition = tri!(map.next_value()),
324            "metadata" => metadata = tri!(map.next_value()),
325            "links" => links = tri!(map.next_value()),
326            "publish" => publish = tri!(map.next_value()),
327            "default_run" => default_run = tri!(map.next_value()),
328            "rust_version" => {
329                let s = tri!(map.next_value::<Option<String>>());
330                if let Some(s) = s {
331                    rust_version = Some(tri!(deserialize_rust_version(s)));
332                }
333            }
334            _ => {
335                tri!(map.next_value::<Ignore>());
336            }
337        }
338    }
339
340    Ok(Package {
341        name: required!(name),
342        version: required!(version),
343        authors,
344        id: required!(id),
345        source,
346        description,
347        dependencies: required!(dependencies),
348        license,
349        license_file,
350        targets: required!(targets),
351        features: required!(features),
352        manifest_path: required!(manifest_path),
353        categories,
354        keywords,
355        readme,
356        repository,
357        homepage,
358        documentation,
359        edition,
360        metadata,
361        links,
362        publish,
363        default_run,
364        rust_version,
365    })
366});
367
368map!(Target, map, {
369    let mut name = None;
370    let mut kind = None;
371    let mut crate_types = Vec::new();
372    let mut required_features = Vec::new();
373    let mut src_path = None;
374    let mut edition = Edition::default();
375    let mut doctest = true;
376    let mut test = true;
377    let mut doc = true;
378
379    while let Some(key) = tri!(map.next_key::<Key<'de>>()) {
380        match key.as_ref() {
381            "name" => name = Some(tri!(map.next_value())),
382            "kind" => kind = Some(tri!(map.next_value())),
383            "crate_types" => crate_types = tri!(map.next_value()),
384            "required-features" => required_features = tri!(map.next_value()),
385            "src_path" => src_path = Some(tri!(map.next_value())),
386            "edition" => edition = tri!(map.next_value()),
387            "doctest" => doctest = tri!(map.next_value()),
388            "test" => test = tri!(map.next_value()),
389            "doc" => doc = tri!(map.next_value()),
390            _ => {
391                tri!(map.next_value::<Ignore>());
392            }
393        }
394    }
395
396    Ok(Target {
397        name: required!(name),
398        kind: required!(kind),
399        crate_types,
400        required_features,
401        src_path: required!(src_path),
402        edition,
403        doctest,
404        test,
405        doc,
406    })
407});
408
409impl<'de> Deserialize<'de> for Source {
410    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
411    where
412        D: Deserializer<'de>,
413    {
414        Ok(Self {
415            repr: tri!(String::deserialize(deserializer)),
416        })
417    }
418}
419
420/// As per the Cargo Book the [`rust-version` field](https://doc.rust-lang.org/cargo/reference/manifest.html#the-rust-version-field) must:
421///
422/// > be a bare version number with two or three components;
423/// > it cannot include semver operators or pre-release identifiers.
424///
425/// [`semver::Version`] however requires three components. This function takes
426/// care of appending `.0` if the provided version number only has two components
427/// and ensuring that it does not contain a pre-release version or build metadata.
428fn deserialize_rust_version<E: Error>(mut buf: String) -> Result<semver::Version, E> {
429    for c in buf.chars() {
430        if c == '-' {
431            return Err(E::custom(
432                "pre-release identifiers are not supported in rust-version",
433            ));
434        } else if c == '+' {
435            return Err(E::custom("build metadata is not supported in rust-version"));
436        }
437    }
438
439    if buf.matches('.').count() == 1 {
440        // e.g. 1.0 -> 1.0.0
441        buf.push_str(".0");
442    }
443
444    Version::parse(&buf).map_err(E::custom)
445}
446
447pub struct Ignore;
448
449impl<'de> Visitor<'de> for Ignore {
450    type Value = Self;
451
452    fn expecting(&self, _formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
453        Ok(())
454    }
455
456    #[inline]
457    fn visit_bool<E>(self, _x: bool) -> Result<Self::Value, E> {
458        Ok(Self)
459    }
460
461    #[inline]
462    fn visit_i64<E>(self, _x: i64) -> Result<Self::Value, E> {
463        Ok(Self)
464    }
465
466    #[inline]
467    fn visit_i128<E>(self, _x: i128) -> Result<Self::Value, E> {
468        Ok(Self)
469    }
470
471    #[inline]
472    fn visit_u64<E>(self, _x: u64) -> Result<Self::Value, E> {
473        Ok(Self)
474    }
475
476    #[inline]
477    fn visit_u128<E>(self, _x: u128) -> Result<Self::Value, E> {
478        Ok(Self)
479    }
480
481    #[inline]
482    fn visit_f64<E>(self, _x: f64) -> Result<Self::Value, E> {
483        Ok(Self)
484    }
485
486    #[inline]
487    fn visit_str<E>(self, _s: &str) -> Result<Self::Value, E>
488    where
489        E: Error,
490    {
491        Ok(Self)
492    }
493
494    #[inline]
495    fn visit_none<E>(self) -> Result<Self::Value, E> {
496        Ok(Self)
497    }
498
499    #[inline]
500    fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
501    where
502        D: Deserializer<'de>,
503    {
504        Self::deserialize(deserializer)
505    }
506
507    #[inline]
508    fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
509    where
510        D: Deserializer<'de>,
511    {
512        Self::deserialize(deserializer)
513    }
514
515    #[inline]
516    fn visit_unit<E>(self) -> Result<Self::Value, E> {
517        Ok(Self)
518    }
519
520    #[inline]
521    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
522    where
523        A: serde::de::SeqAccess<'de>,
524    {
525        while let Some(Self) = tri!(seq.next_element()) {}
526        Ok(Self)
527    }
528
529    #[inline]
530    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
531    where
532        A: serde::de::MapAccess<'de>,
533    {
534        while let Some((Self, Self)) = tri!(map.next_entry()) {}
535        Ok(Self)
536    }
537
538    #[inline]
539    fn visit_bytes<E>(self, _bytes: &[u8]) -> Result<Self::Value, E>
540    where
541        E: Error,
542    {
543        Ok(Self)
544    }
545
546    fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
547    where
548        A: serde::de::EnumAccess<'de>,
549    {
550        use serde::de::VariantAccess;
551        tri!(data.variant::<Self>()).1.newtype_variant()
552    }
553}
554
555impl<'de> Deserialize<'de> for Ignore {
556    #[inline]
557    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
558    where
559        D: Deserializer<'de>,
560    {
561        deserializer.deserialize_ignored_any(Self)
562    }
563}