pedant_core/project/cargo_meta.rs
1use std::collections::BTreeMap;
2
3use serde::Deserialize;
4
5/// The subset of `cargo metadata --format-version 1` output that
6/// `feature-boundary` needs. Unknown fields are ignored.
7#[derive(Debug, Clone, Default, Deserialize)]
8pub struct CargoMetadata {
9 /// Every package in the dependency graph.
10 #[serde(default)]
11 pub packages: Vec<CargoPackage>,
12 /// Package ids of the workspace members built by default.
13 #[serde(default)]
14 pub workspace_default_members: Vec<String>,
15 /// Package ids of all workspace members (fallback when
16 /// `workspace_default_members` is absent on older Cargo).
17 #[serde(default)]
18 pub workspace_members: Vec<String>,
19}
20
21/// A single resolved package.
22#[derive(Debug, Clone, Deserialize)]
23pub struct CargoPackage {
24 /// Crate name.
25 pub name: String,
26 /// Opaque package id, matched against the workspace-member lists.
27 pub id: String,
28 /// Feature definitions: feature name → the features/deps it enables.
29 #[serde(default)]
30 pub features: BTreeMap<String, Vec<String>>,
31 /// Declared dependencies.
32 #[serde(default)]
33 pub dependencies: Vec<CargoDependency>,
34}
35
36/// A dependency declaration on a package.
37#[derive(Debug, Clone, Deserialize)]
38pub struct CargoDependency {
39 /// The depended-on crate's name.
40 pub name: String,
41 /// `null`/absent for normal, `"dev"`, or `"build"`.
42 #[serde(default)]
43 pub kind: Option<String>,
44 /// Features requested on the dependency.
45 #[serde(default)]
46 pub features: Vec<String>,
47 /// Whether the dependency's default features are enabled (defaults to true).
48 #[serde(default = "default_uses_default_features")]
49 pub uses_default_features: bool,
50 /// Whether the dependency is optional.
51 #[serde(default)]
52 pub optional: bool,
53 /// The local alias when the dependency is renamed.
54 #[serde(default)]
55 pub rename: Option<String>,
56}
57
58impl CargoDependency {
59 /// The name this dependency is referred to by in feature strings
60 /// (the rename if present, else the crate name).
61 pub fn local_name(&self) -> &str {
62 self.rename.as_deref().unwrap_or(&self.name)
63 }
64}
65
66fn default_uses_default_features() -> bool {
67 true
68}