sps_common/dependency/
definition.rs1use std::fmt;
3
4use bitflags::bitflags;
5use serde::{Deserialize, Serialize};
6
7bitflags! {
8 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
9 pub struct DependencyTag: u8 {
10 const RUNTIME = 0b00000001;
11 const BUILD = 0b00000010;
12 const TEST = 0b00000100;
13 const OPTIONAL = 0b00001000;
14 const RECOMMENDED = 0b00010000;
15 }
16}
17
18impl Default for DependencyTag {
19 fn default() -> Self {
20 Self::RUNTIME
21 }
22}
23
24impl fmt::Display for DependencyTag {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 write!(f, "{self:?}")
27 }
28}
29
30#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
31pub struct Dependency {
32 pub name: String,
33 #[serde(default)]
34 pub tags: DependencyTag,
35}
36
37impl Dependency {
38 pub fn new_runtime(name: impl Into<String>) -> Self {
39 Self {
40 name: name.into(),
41 tags: DependencyTag::RUNTIME,
42 }
43 }
44
45 pub fn new_with_tags(name: impl Into<String>, tags: DependencyTag) -> Self {
46 Self {
47 name: name.into(),
48 tags,
49 }
50 }
51}
52
53pub trait DependencyExt {
54 fn filter_by_tags(&self, include: DependencyTag, exclude: DependencyTag) -> Vec<&Dependency>;
55 fn runtime(&self) -> Vec<&Dependency>;
56 fn build_time(&self) -> Vec<&Dependency>;
57}
58
59impl DependencyExt for Vec<Dependency> {
60 fn filter_by_tags(&self, include: DependencyTag, exclude: DependencyTag) -> Vec<&Dependency> {
61 self.iter()
62 .filter(|dep| dep.tags.contains(include) && !dep.tags.intersects(exclude))
63 .collect()
64 }
65
66 fn runtime(&self) -> Vec<&Dependency> {
67 self.iter()
71 .filter(|dep| {
72 dep.tags.intersects(
73 DependencyTag::RUNTIME | DependencyTag::RECOMMENDED | DependencyTag::OPTIONAL,
74 )
75 })
76 .collect()
77 }
78
79 fn build_time(&self) -> Vec<&Dependency> {
80 self.filter_by_tags(DependencyTag::BUILD, DependencyTag::empty())
81 }
82}