cargo_hackerman/
metadata.rs1use cargo_metadata::Dependency;
2use cargo_platform::Cfg;
3
4use crate::{feat_graph::Feature, hack::Collect};
5
6#[derive(Eq, PartialEq, Clone, Debug, Copy, Hash, PartialOrd, Ord)]
7pub enum DependencyKind {
9 Normal,
11 Development,
13 Build,
15 Unknown,
16}
17
18impl From<cargo_metadata::DependencyKind> for DependencyKind {
19 fn from(x: cargo_metadata::DependencyKind) -> Self {
20 match x {
21 cargo_metadata::DependencyKind::Normal => DependencyKind::Normal,
22 cargo_metadata::DependencyKind::Development => DependencyKind::Development,
23 cargo_metadata::DependencyKind::Build => DependencyKind::Build,
24 _ => DependencyKind::Unknown,
25 }
26 }
27}
28
29#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
30pub struct DepKindInfo {
31 pub kind: DependencyKind,
32 pub target: Option<cargo_platform::Platform>,
33}
34
35impl DepKindInfo {
36 pub const NORMAL: Self = Self {
37 kind: DependencyKind::Normal,
38 target: None,
39 };
40
41 pub const DEV: Self = Self {
42 kind: DependencyKind::Development,
43 target: None,
44 };
45
46 fn satisfies(
47 &self,
48 source: Feature,
49 filter: Collect,
50 platforms: &[&str],
51 cfgs: &[Cfg],
52 ) -> bool {
53 if self.kind == DependencyKind::Development {
54 match filter {
55 Collect::AllTargets | Collect::Target | Collect::NoDev | Collect::NormalOnly => {
56 return false
57 }
58 Collect::MemberDev(pid) => {
59 if let Some(this_fid) = source.fid() {
60 {
61 if this_fid.pid != pid {
62 return false;
63 }
64 }
65 }
66 }
67 Collect::DevTarget => {
68 if !source.is_workspace() {
69 return false;
70 }
71 }
72 };
73 }
74
75 self.target
76 .as_ref()
77 .map_or(true, |p| p.matches(platforms[0], cfgs))
78 }
79}
80
81impl From<&Dependency> for DepKindInfo {
82 fn from(dep: &Dependency) -> Self {
83 Self {
84 kind: dep.kind.into(),
85 target: dep.target.clone(),
86 }
87 }
88}
89
90#[derive(Debug, Clone)]
91pub struct Link {
92 pub optional: bool,
94 pub kinds: Vec<DepKindInfo>,
95}
96
97impl Link {
98 pub const ALWAYS: Link = Link {
100 optional: false,
101 kinds: Vec::new(),
102 };
103
104 pub const OPT: Link = Link {
106 optional: true,
107 kinds: Vec::new(),
108 };
109
110 pub(crate) fn is_dev_only(&self) -> bool {
111 self.kinds
112 .iter()
113 .all(|k| k.kind == DependencyKind::Development)
114 }
115 pub(crate) fn is_normal(&self) -> bool {
116 self.kinds.iter().any(|k| k.kind == DependencyKind::Normal)
117 }
118
119 pub(crate) fn satisfies(
120 &self,
121 source: Feature,
122 filter: Collect,
123 platforms: &[&str],
124 cfgs: &[Cfg],
125 ) -> bool {
126 self.kinds
127 .iter()
128 .any(|kind| kind.satisfies(source, filter, platforms, cfgs))
129 }
130}