1use crate::crates::CrateId;
4use crate::versions::VersionId;
5use semver::VersionReq;
6use serde::de::{Deserialize, Deserializer, Unexpected, Visitor};
7use serde_derive::Deserialize;
8use std::fmt;
9
10#[derive(Deserialize, Clone, Debug)]
12#[serde(deny_unknown_fields)]
13#[non_exhaustive]
14pub struct Row {
15 pub id: u32,
17 pub version_id: VersionId,
18 pub crate_id: CrateId,
19 #[serde(deserialize_with = "version_req")]
20 pub req: VersionReq,
21 #[serde(deserialize_with = "crate::bool::de")]
22 pub optional: bool,
23 #[serde(deserialize_with = "crate::bool::de")]
24 pub default_features: bool,
25 #[serde(deserialize_with = "features_set")]
26 pub features: Vec<String>,
27 pub target: String,
28 pub kind: DependencyKind,
29 #[serde(default)]
30 pub explicit_name: Option<String>,
31}
32
33#[derive(Copy, Clone, Debug)]
34pub enum DependencyKind {
35 Normal,
37 Build,
39 Dev,
41}
42
43struct DependencyKindVisitor;
44
45impl<'de> Visitor<'de> for DependencyKindVisitor {
46 type Value = DependencyKind;
47
48 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
49 formatter.write_str("dependency kind (0, 1, 2)")
50 }
51
52 fn visit_u8<E>(self, kind: u8) -> Result<Self::Value, E>
53 where
54 E: serde::de::Error,
55 {
56 match kind {
57 0 => Ok(DependencyKind::Normal),
58 1 => Ok(DependencyKind::Build),
59 2 => Ok(DependencyKind::Dev),
60 _ => Err(serde::de::Error::invalid_value(
61 Unexpected::Unsigned(kind as u64),
62 &self,
63 )),
64 }
65 }
66}
67
68impl<'de> Deserialize<'de> for DependencyKind {
69 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
70 where
71 D: Deserializer<'de>,
72 {
73 deserializer.deserialize_u8(DependencyKindVisitor)
74 }
75}
76
77fn compat(string: &str) -> Option<VersionReq> {
78 let deprecated = match string {
79 "^0-.11.0" => "^0.11.0",
80 "^0.1-alpha.0" => "^0.1.0-alpha.0",
81 "^0.51-oldsyn" => "^0.51.1-oldsyn",
82 "~2.0-2.2" => ">=2.0, <=2.2",
83 _ => return None,
84 };
85 Some(deprecated.parse().unwrap())
86}
87
88struct VersionReqVisitor;
89
90impl<'de> Visitor<'de> for VersionReqVisitor {
91 type Value = VersionReq;
92
93 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
94 formatter.write_str("semver version req")
95 }
96
97 fn visit_str<E>(self, string: &str) -> Result<Self::Value, E>
98 where
99 E: serde::de::Error,
100 {
101 match string.parse() {
102 Ok(version) => Ok(version),
103 Err(err) => {
104 if let Some(version) = compat(string) {
105 Ok(version)
106 } else {
107 Err(serde::de::Error::custom(format_args!(
108 "{}: req {}",
109 err, string,
110 )))
111 }
112 }
113 }
114 }
115}
116
117fn version_req<'de, D>(deserializer: D) -> Result<VersionReq, D::Error>
118where
119 D: Deserializer<'de>,
120{
121 deserializer.deserialize_str(VersionReqVisitor)
122}
123
124fn features_set<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
125where
126 D: Deserializer<'de>,
127{
128 crate::set::de(deserializer, "features set")
129}