mithril_common/
api_version.rs1include!(concat!(env!("OUT_DIR"), "/open_api.rs"));
3use anyhow::anyhow;
4use semver::{Version, VersionReq};
5use std::collections::HashMap;
6use std::sync::Arc;
7
8use crate::era::EraChecker;
9use crate::StdResult;
10
11#[derive(Clone)]
13pub struct APIVersionProvider {
14 era_checker: Arc<EraChecker>,
15 open_api_versions: HashMap<OpenAPIFileName, Version>,
16}
17
18impl APIVersionProvider {
19 pub fn new(era_checker: Arc<EraChecker>) -> Self {
21 Self {
22 era_checker,
23 open_api_versions: get_open_api_versions_mapping(),
24 }
25 }
26
27 pub fn compute_current_version(&self) -> StdResult<Version> {
29 let current_era = self.era_checker.current_era();
30 let open_api_spec_file_name_default = "openapi.yaml";
31 let open_api_spec_file_name_era = &format!("openapi-{current_era}.yaml");
32 let open_api_version = self
33 .open_api_versions
34 .get(open_api_spec_file_name_era)
35 .unwrap_or(
36 self.open_api_versions
37 .get(open_api_spec_file_name_default)
38 .ok_or_else(|| anyhow!("Missing default API version"))?,
39 );
40
41 Ok(open_api_version.clone())
42 }
43
44 pub fn compute_current_version_requirement(&self) -> StdResult<VersionReq> {
46 let version = &self.compute_current_version()?;
47 let version_req = if version.major > 0 {
48 format!("={}", version.major)
49 } else {
50 format!("={}.{}", version.major, version.minor)
51 };
52
53 Ok(VersionReq::parse(&version_req)?)
54 }
55
56 pub fn compute_all_versions_sorted() -> StdResult<Vec<Version>> {
58 let mut versions: Vec<Version> = get_open_api_versions_mapping().into_values().collect();
59 versions.sort();
60 Ok(versions)
61 }
62
63 pub fn update_open_api_versions(
65 &mut self,
66 open_api_versions: HashMap<OpenAPIFileName, Version>,
67 ) {
68 self.open_api_versions = open_api_versions;
69 }
70}
71
72#[cfg(test)]
73mod test {
74 use semver::Version;
75 use std::{collections::HashMap, sync::Arc};
76
77 use crate::{
78 api_version::APIVersionProvider,
79 entities::Epoch,
80 era::{EraChecker, SupportedEra},
81 };
82
83 #[test]
84 fn test_compute_current_version_default() {
85 let era_checker = EraChecker::new(SupportedEra::dummy(), Epoch(1));
86 let mut version_provider = APIVersionProvider::new(Arc::new(era_checker));
87 let mut open_api_versions = HashMap::new();
88 open_api_versions.insert("openapi.yaml".to_string(), Version::new(1, 2, 3));
89 version_provider.update_open_api_versions(open_api_versions);
90 let api_version_provider = Arc::new(version_provider);
91
92 assert_eq!(
93 "1.2.3".to_string(),
94 api_version_provider
95 .compute_current_version()
96 .unwrap()
97 .to_string()
98 )
99 }
100
101 #[test]
102 fn test_compute_current_version_era_specific() {
103 let era_checker = EraChecker::new(SupportedEra::dummy(), Epoch(1));
104 let mut version_provider = APIVersionProvider::new(Arc::new(era_checker));
105 let mut open_api_versions = HashMap::new();
106 open_api_versions.insert("openapi.yaml".to_string(), Version::new(1, 2, 3));
107 open_api_versions.insert(
108 format!("openapi-{}.yaml", SupportedEra::dummy()),
109 Version::new(2, 1, 0),
110 );
111 version_provider.update_open_api_versions(open_api_versions);
112 let api_version_provider = Arc::new(version_provider);
113
114 assert_eq!(
115 "2.1.0".to_string(),
116 api_version_provider
117 .compute_current_version()
118 .unwrap()
119 .to_string()
120 )
121 }
122
123 #[test]
124 fn test_compute_current_version_requirement_beta() {
125 let era_checker = EraChecker::new(SupportedEra::dummy(), Epoch(1));
126 let mut version_provider = APIVersionProvider::new(Arc::new(era_checker));
127 let mut open_api_versions = HashMap::new();
128 open_api_versions.insert("openapi.yaml".to_string(), Version::new(0, 2, 3));
129 version_provider.update_open_api_versions(open_api_versions);
130 let api_version_provider = Arc::new(version_provider);
131
132 assert_eq!(
133 "=0.2".to_string(),
134 api_version_provider
135 .compute_current_version_requirement()
136 .unwrap()
137 .to_string()
138 )
139 }
140
141 #[test]
142 fn test_compute_current_version_requirement_stable() {
143 let era_checker = EraChecker::new(SupportedEra::dummy(), Epoch(1));
144 let mut version_provider = APIVersionProvider::new(Arc::new(era_checker));
145 let mut open_api_versions = HashMap::new();
146 open_api_versions.insert("openapi.yaml".to_string(), Version::new(3, 2, 1));
147 version_provider.update_open_api_versions(open_api_versions);
148 let api_version_provider = Arc::new(version_provider);
149
150 assert_eq!(
151 "=3".to_string(),
152 api_version_provider
153 .compute_current_version_requirement()
154 .unwrap()
155 .to_string()
156 )
157 }
158
159 #[test]
160 fn test_compute_all_versions_sorted() {
161 let all_versions_sorted = APIVersionProvider::compute_all_versions_sorted()
162 .expect("Computing the list of all sorted versions should not fail");
163
164 assert!(!all_versions_sorted.is_empty());
165 }
166}