db_dump/
dependencies.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//! <b style="font-variant:small-caps">dependencies.csv</b>

use crate::crates::CrateId;
use crate::versions::VersionId;
use semver::VersionReq;
use serde::de::{Deserialize, Deserializer, Unexpected, Visitor};
use serde_derive::Deserialize;
use std::fmt;

/// One row of **dependencies.csv**.
#[derive(Deserialize, Clone, Debug)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct Row {
    /// PRIMARY KEY
    pub id: u32,
    pub version_id: VersionId,
    pub crate_id: CrateId,
    #[serde(deserialize_with = "version_req")]
    pub req: VersionReq,
    #[serde(deserialize_with = "crate::bool::de")]
    pub optional: bool,
    #[serde(deserialize_with = "crate::bool::de")]
    pub default_features: bool,
    #[serde(deserialize_with = "features_set")]
    pub features: Vec<String>,
    pub target: String,
    pub kind: DependencyKind,
    #[serde(default)]
    pub explicit_name: Option<String>,
}

#[derive(Copy, Clone, Debug)]
pub enum DependencyKind {
    /// kind=0
    Normal,
    /// kind=1
    Build,
    /// kind=2
    Dev,
}

struct DependencyKindVisitor;

impl<'de> Visitor<'de> for DependencyKindVisitor {
    type Value = DependencyKind;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("dependency kind (0, 1, 2)")
    }

    fn visit_u8<E>(self, kind: u8) -> Result<Self::Value, E>
    where
        E: serde::de::Error,
    {
        match kind {
            0 => Ok(DependencyKind::Normal),
            1 => Ok(DependencyKind::Build),
            2 => Ok(DependencyKind::Dev),
            _ => Err(serde::de::Error::invalid_value(
                Unexpected::Unsigned(kind as u64),
                &self,
            )),
        }
    }
}

impl<'de> Deserialize<'de> for DependencyKind {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_u8(DependencyKindVisitor)
    }
}

fn compat(string: &str) -> Option<VersionReq> {
    let deprecated = match string {
        "^0-.11.0" => "^0.11.0",
        "^0.1-alpha.0" => "^0.1.0-alpha.0",
        "^0.51-oldsyn" => "^0.51.1-oldsyn",
        "~2.0-2.2" => ">=2.0, <=2.2",
        _ => return None,
    };
    Some(deprecated.parse().unwrap())
}

struct VersionReqVisitor;

impl<'de> Visitor<'de> for VersionReqVisitor {
    type Value = VersionReq;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("semver version req")
    }

    fn visit_str<E>(self, string: &str) -> Result<Self::Value, E>
    where
        E: serde::de::Error,
    {
        match string.parse() {
            Ok(version) => Ok(version),
            Err(err) => {
                if let Some(version) = compat(string) {
                    Ok(version)
                } else {
                    Err(serde::de::Error::custom(format_args!(
                        "{}: req {}",
                        err, string,
                    )))
                }
            }
        }
    }
}

fn version_req<'de, D>(deserializer: D) -> Result<VersionReq, D::Error>
where
    D: Deserializer<'de>,
{
    deserializer.deserialize_str(VersionReqVisitor)
}

fn features_set<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
where
    D: Deserializer<'de>,
{
    crate::set::de(deserializer, "features set")
}