abstract_std/objects/
dependency.rs1use semver::{Comparator, Version};
3use serde::{Deserialize, Serialize};
4
5use super::module::ModuleId;
6
7#[derive(Debug, Clone, PartialEq)]
9pub struct StaticDependency {
10 pub id: ModuleId<'static>,
11 pub version_req: &'static [&'static str],
12}
13
14impl StaticDependency {
15 pub const fn new(
16 module_id: ModuleId<'static>,
17 version_requirement: &'static [&'static str],
18 ) -> Self {
19 Self {
20 id: module_id,
21 version_req: version_requirement,
22 }
23 }
24
25 pub fn check(&self) -> Result<(), semver::Error> {
27 for req in self.version_req {
28 Comparator::parse(req)?;
29 }
30 Ok(())
31 }
32
33 pub fn matches(&self, version: &Version) -> bool {
35 self.version_req
36 .iter()
37 .all(|req| Comparator::parse(req).unwrap().matches(version))
38 }
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
43pub struct Dependency {
44 pub id: String,
45 pub version_req: Vec<Comparator>,
46}
47
48impl From<&StaticDependency> for Dependency {
49 fn from(dep: &StaticDependency) -> Self {
50 Self {
51 id: dep.id.to_string(),
52 version_req: dep.version_req.iter().map(|s| s.parse().unwrap()).collect(),
53 }
54 }
55}
56
57#[cosmwasm_schema::cw_serde]
58pub struct DependencyResponse {
59 pub id: String,
60 pub version_req: Vec<String>,
61}
62
63impl From<Dependency> for DependencyResponse {
64 fn from(dep: Dependency) -> Self {
65 Self {
66 id: dep.id,
67 version_req: dep
68 .version_req
69 .into_iter()
70 .map(|comp| comp.to_string())
71 .collect(),
72 }
73 }
74}
75
76#[cfg(test)]
77mod test {
78 #![allow(clippy::needless_borrows_for_generic_args)]
79
80 use super::*;
81
82 #[coverage_helper::test]
83 fn test_static_constructor() {
84 const VERSION_CONSTRAINT: [&str; 1] = ["^1.0.0"];
85
86 let dep = StaticDependency::new("test", &VERSION_CONSTRAINT);
87
88 assert_eq!(dep.id, "test");
89 assert_eq!(dep.version_req.to_vec(), VERSION_CONSTRAINT.to_vec());
90 }
91
92 #[coverage_helper::test]
93 fn static_check_passes() {
94 const VERSION_CONSTRAINT: [&str; 1] = ["^1.0.0"];
95
96 let dep = StaticDependency::new("test", &VERSION_CONSTRAINT);
97
98 assert!(dep.check().is_ok());
99 }
100
101 #[coverage_helper::test]
102 fn static_check_passes_without_comparator() {
103 const VERSION_CONSTRAINT: [&str; 1] = ["1.0.0"];
104
105 let dep = StaticDependency::new("test", &VERSION_CONSTRAINT);
106
107 assert!(dep.check().is_ok());
108 }
109
110 #[coverage_helper::test]
111 fn static_check_fails() {
112 const VERSION_CONSTRAINT: [&str; 1] = ["^1e.0"];
113
114 let dep = StaticDependency::new("test", &VERSION_CONSTRAINT);
115
116 assert!(dep.check().is_err());
117 }
118
119 #[coverage_helper::test]
120 fn matches_should_match_matching_versions() {
121 const VERSION_CONSTRAINT: [&str; 1] = ["^1.0.0"];
122
123 let dep = StaticDependency::new("test", &VERSION_CONSTRAINT);
124
125 assert!(dep.matches(&Version::parse("1.0.0").unwrap()));
126 assert!(dep.matches(&Version::parse("1.1.0").unwrap()));
127 assert!(dep.matches(&Version::parse("1.1.1").unwrap()));
128 }
129
130 #[coverage_helper::test]
131 fn matches_should_not_match_non_matching_versions() {
132 const VERSION_CONSTRAINT: [&str; 1] = ["^1.0.0"];
133
134 let dep = StaticDependency::new("test", &VERSION_CONSTRAINT);
135
136 assert!(!dep.matches(&Version::parse("2.0.0").unwrap()));
137 assert!(!dep.matches(&Version::parse("0.1.0").unwrap()));
138 assert!(!dep.matches(&Version::parse("0.1.1").unwrap()));
139 }
140
141 #[coverage_helper::test]
142 fn test_dependency_from_static() {
143 const VERSION_CONSTRAINT: [&str; 1] = ["^1.0.0"];
144
145 let dep = &StaticDependency::new("test", &VERSION_CONSTRAINT);
146
147 let dep: Dependency = dep.into();
148
149 assert_eq!(dep.id, "test".to_string());
150 assert_eq!(dep.version_req, vec![Comparator::parse("^1.0.0").unwrap()]);
151 }
152}