use super::*;
use serde::de::{Deserialize, Deserializer, Error, Visitor};
type Key<'de> = std::borrow::Cow<'de, str>;
macro_rules! tri {
($res:expr) => {
match $res {
Ok(r) => r,
Err(err) => return Err(err),
}
};
}
impl<'de> Deserialize<'de> for PackageId {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(Self {
repr: tri!(String::deserialize(deserializer)),
})
}
}
macro_rules! map {
($kind:ty, $map:ident, $func:block) => {
impl<'de> Deserialize<'de> for $kind {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct V;
impl<'de> Visitor<'de> for V {
type Value = $kind;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(concat!("an ", stringify!($kind)))
}
fn visit_map<A>(self, mut $map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
$func
}
}
deserializer.deserialize_map(V)
}
}
};
}
macro_rules! parse {
($kind:ty) => {
impl<'de> Deserialize<'de> for $kind {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = tri!(std::borrow::Cow::<'de, str>::deserialize(deserializer));
s.parse().map_err(|err| Error::custom(err))
}
}
};
}
macro_rules! required {
($name:ident) => {
if let Some(v) = $name {
v
} else {
return Err(Error::missing_field(stringify!($name)));
}
};
}
map!(Metadata, map, {
let mut packages = None;
let mut workspace_members = None;
let mut workspace_default_members = None;
let mut resolve = None;
let mut workspace_root = None;
let mut target_directory = None;
let mut workspace_metadata = serde_json::Value::Null;
let mut version = 0;
while let Some(key) = tri!(map.next_key::<Key<'de>>()) {
match key.as_ref() {
"packages" => packages = Some(tri!(map.next_value())),
"workspace_members" => workspace_members = Some(tri!(map.next_value())),
"workspace_default_members" => workspace_default_members = Some(tri!(map.next_value())),
"resolve" => resolve = Some(tri!(map.next_value())),
"workspace_root" => workspace_root = Some(tri!(map.next_value())),
"target_directory" => target_directory = Some(tri!(map.next_value())),
"metadata" => workspace_metadata = tri!(map.next_value()),
"version" => version = tri!(map.next_value()),
_ => {
tri!(map.next_value::<Ignore>());
}
}
}
Ok(Metadata {
packages: required!(packages),
workspace_members: required!(workspace_members),
workspace_default_members: WorkspaceDefaultMembers(workspace_default_members),
resolve,
workspace_root: required!(workspace_root),
target_directory: required!(target_directory),
workspace_metadata,
version,
})
});
map!(Resolve, map, {
let mut nodes = None;
let mut root = None;
while let Some(key) = tri!(map.next_key::<Key<'de>>()) {
match key.as_ref() {
"nodes" => nodes = Some(tri!(map.next_value())),
"root" => root = Some(tri!(map.next_value())),
_ => {
tri!(map.next_value::<Ignore>());
}
}
}
Ok(Resolve {
nodes: required!(nodes),
root: required!(root),
})
});
map!(Node, map, {
let mut id = None;
let mut deps = Vec::new();
let mut dependencies = None;
let mut features = Vec::new();
while let Some(key) = tri!(map.next_key::<Key<'de>>()) {
match key.as_ref() {
"id" => id = Some(tri!(map.next_value())),
"deps" => deps = tri!(map.next_value()),
"dependencies" => dependencies = Some(tri!(map.next_value())),
"features" => features = tri!(map.next_value()),
_ => {
tri!(map.next_value::<Ignore>());
}
}
}
Ok(Node {
id: required!(id),
deps,
dependencies: required!(dependencies),
features,
})
});
map!(NodeDep, map, {
let mut name = None;
let mut pkg = None;
let mut dep_kinds = Vec::new();
while let Some(key) = tri!(map.next_key::<Key<'de>>()) {
match key.as_ref() {
"name" => name = Some(tri!(map.next_value())),
"pkg" => pkg = Some(tri!(map.next_value())),
"dep_kinds" => dep_kinds = tri!(map.next_value()),
_ => {
tri!(map.next_value::<Ignore>());
}
}
}
Ok(NodeDep {
name: required!(name),
pkg: required!(pkg),
dep_kinds,
})
});
map!(DepKindInfo, map, {
let mut kind = DependencyKind::Normal;
let mut target = None;
while let Some(key) = tri!(map.next_key::<Key<'de>>()) {
match key.as_ref() {
"kind" => kind = tri!(map.next_value()),
"target" => target = tri!(map.next_value()),
_ => {
tri!(map.next_value::<Ignore>());
}
}
}
Ok(DepKindInfo { kind, target })
});
impl<'de> Deserialize<'de> for DependencyKind {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let kind = tri!(Option::<std::borrow::Cow<'de, str>>::deserialize(
deserializer
));
if let Some(kind) = kind {
Ok(match kind.as_ref() {
"normal" => Self::Normal,
"dev" => Self::Development,
"build" => Self::Build,
unknown => {
return Err(Error::unknown_variant(unknown, &["normal", "dev", "build"]));
}
})
} else {
Ok(Self::Normal)
}
}
}
map!(Dependency, map, {
let mut name = None;
let mut source = None;
let mut req = None;
let mut kind = DependencyKind::Normal;
let mut optional = None;
let mut uses_default_features = None;
let mut features = None;
let mut target = None;
let mut rename = None;
let mut registry = None;
let mut path = None;
while let Some(key) = tri!(map.next_key::<Key<'de>>()) {
match key.as_ref() {
"name" => name = Some(tri!(map.next_value())),
"source" => source = tri!(map.next_value()),
"req" => req = Some(tri!(map.next_value())),
"kind" => kind = tri!(map.next_value()),
"optional" => optional = Some(tri!(map.next_value())),
"uses_default_features" => uses_default_features = Some(tri!(map.next_value())),
"features" => features = Some(tri!(map.next_value())),
"target" => target = tri!(map.next_value()),
"rename" => rename = tri!(map.next_value()),
"registry" => registry = tri!(map.next_value()),
"path" => path = tri!(map.next_value()),
_ => {
tri!(map.next_value::<Ignore>());
}
}
}
Ok(Dependency {
name: required!(name),
source,
req: required!(req),
kind,
optional: required!(optional),
uses_default_features: required!(uses_default_features),
features: required!(features),
target,
rename,
registry,
path,
})
});
parse!(TargetKind);
parse!(CrateType);
parse!(Edition);
map!(Package, map, {
let mut name = None;
let mut version = None;
let mut authors = Vec::new();
let mut id = None;
let mut source = None;
let mut description = None;
let mut dependencies = None;
let mut license = None;
let mut license_file = None;
let mut targets = None;
let mut features = None;
let mut manifest_path = None;
let mut categories = Vec::new();
let mut keywords = Vec::new();
let mut readme = None;
let mut repository = None;
let mut homepage = None;
let mut documentation = None;
let mut edition = Edition::default();
let mut metadata = serde_json::Value::Null;
let mut links = None;
let mut publish = None;
let mut default_run = None;
let mut rust_version = None;
while let Some(key) = tri!(map.next_key::<Key<'de>>()) {
match key.as_ref() {
"name" => name = Some(tri!(map.next_value())),
"version" => version = Some(tri!(map.next_value())),
"authors" => authors = tri!(map.next_value()),
"id" => id = Some(tri!(map.next_value())),
"source" => source = tri!(map.next_value()),
"description" => description = tri!(map.next_value()),
"dependencies" => dependencies = Some(tri!(map.next_value())),
"license" => license = tri!(map.next_value()),
"license_file" => license_file = tri!(map.next_value()),
"targets" => targets = Some(tri!(map.next_value())),
"features" => features = Some(tri!(map.next_value())),
"manifest_path" => manifest_path = Some(tri!(map.next_value())),
"categories" => categories = tri!(map.next_value()),
"keywords" => keywords = tri!(map.next_value()),
"readme" => readme = tri!(map.next_value()),
"repository" => repository = tri!(map.next_value()),
"homepage" => homepage = tri!(map.next_value()),
"documentation" => documentation = tri!(map.next_value()),
"edition" => edition = tri!(map.next_value()),
"metadata" => metadata = tri!(map.next_value()),
"links" => links = tri!(map.next_value()),
"publish" => publish = tri!(map.next_value()),
"default_run" => default_run = tri!(map.next_value()),
"rust_version" => {
let s = tri!(map.next_value::<Option<String>>());
if let Some(s) = s {
rust_version = Some(tri!(deserialize_rust_version(s)));
}
}
_ => {
tri!(map.next_value::<Ignore>());
}
}
}
Ok(Package {
name: required!(name),
version: required!(version),
authors,
id: required!(id),
source,
description,
dependencies: required!(dependencies),
license,
license_file,
targets: required!(targets),
features: required!(features),
manifest_path: required!(manifest_path),
categories,
keywords,
readme,
repository,
homepage,
documentation,
edition,
metadata,
links,
publish,
default_run,
rust_version,
})
});
map!(Target, map, {
let mut name = None;
let mut kind = None;
let mut crate_types = Vec::new();
let mut required_features = Vec::new();
let mut src_path = None;
let mut edition = Edition::default();
let mut doctest = true;
let mut test = true;
let mut doc = true;
while let Some(key) = tri!(map.next_key::<Key<'de>>()) {
match key.as_ref() {
"name" => name = Some(tri!(map.next_value())),
"kind" => kind = Some(tri!(map.next_value())),
"crate_types" => crate_types = tri!(map.next_value()),
"required-features" => required_features = tri!(map.next_value()),
"src_path" => src_path = Some(tri!(map.next_value())),
"edition" => edition = tri!(map.next_value()),
"doctest" => doctest = tri!(map.next_value()),
"test" => test = tri!(map.next_value()),
"doc" => doc = tri!(map.next_value()),
_ => {
tri!(map.next_value::<Ignore>());
}
}
}
Ok(Target {
name: required!(name),
kind: required!(kind),
crate_types,
required_features,
src_path: required!(src_path),
edition,
doctest,
test,
doc,
})
});
impl<'de> Deserialize<'de> for Source {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(Self {
repr: tri!(String::deserialize(deserializer)),
})
}
}
fn deserialize_rust_version<E: Error>(mut buf: String) -> Result<semver::Version, E> {
for c in buf.chars() {
if c == '-' {
return Err(E::custom(
"pre-release identifiers are not supported in rust-version",
));
} else if c == '+' {
return Err(E::custom("build metadata is not supported in rust-version"));
}
}
if buf.matches('.').count() == 1 {
buf.push_str(".0");
}
Version::parse(&buf).map_err(E::custom)
}
pub struct Ignore;
impl<'de> Visitor<'de> for Ignore {
type Value = Self;
fn expecting(&self, _formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
Ok(())
}
#[inline]
fn visit_bool<E>(self, _x: bool) -> Result<Self::Value, E> {
Ok(Self)
}
#[inline]
fn visit_i64<E>(self, _x: i64) -> Result<Self::Value, E> {
Ok(Self)
}
#[inline]
fn visit_i128<E>(self, _x: i128) -> Result<Self::Value, E> {
Ok(Self)
}
#[inline]
fn visit_u64<E>(self, _x: u64) -> Result<Self::Value, E> {
Ok(Self)
}
#[inline]
fn visit_u128<E>(self, _x: u128) -> Result<Self::Value, E> {
Ok(Self)
}
#[inline]
fn visit_f64<E>(self, _x: f64) -> Result<Self::Value, E> {
Ok(Self)
}
#[inline]
fn visit_str<E>(self, _s: &str) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Self)
}
#[inline]
fn visit_none<E>(self) -> Result<Self::Value, E> {
Ok(Self)
}
#[inline]
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
Self::deserialize(deserializer)
}
#[inline]
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
Self::deserialize(deserializer)
}
#[inline]
fn visit_unit<E>(self) -> Result<Self::Value, E> {
Ok(Self)
}
#[inline]
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
while let Some(Self) = tri!(seq.next_element()) {}
Ok(Self)
}
#[inline]
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
while let Some((Self, Self)) = tri!(map.next_entry()) {}
Ok(Self)
}
#[inline]
fn visit_bytes<E>(self, _bytes: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Self)
}
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where
A: serde::de::EnumAccess<'de>,
{
use serde::de::VariantAccess;
tri!(data.variant::<Self>()).1.newtype_variant()
}
}
impl<'de> Deserialize<'de> for Ignore {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_ignored_any(Self)
}
}