Skip to content

Commit e00a8b5

Browse files
jiangliualindima
authored andcommitted
Enhance VersionMap to filter out some versions
Current VersionMap implementation assumes all versions lower than VersionMap::latest_version() are supported. That may not be true in some situation. So add `is_supported()` method to VersionMap to filter out some versions. Signed-off-by: Liu Jiang <[email protected]>
1 parent f61cc15 commit e00a8b5

File tree

2 files changed

+79
-2
lines changed

2 files changed

+79
-2
lines changed

coverage_config_x86_64.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"coverage_score": 95.4, "exclude_path": "test", "crate_features": ""}
1+
{"coverage_score": 96.2, "exclude_path": "test", "crate_features": ""}

src/version_map.rs

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,51 @@
6262
6363
use std::any::TypeId;
6464
use std::collections::hash_map::HashMap;
65+
use std::fmt::Debug;
66+
use std::sync::Arc;
6567

6668
const BASE_VERSION: u16 = 1;
6769

70+
/// Trait to check whether is specific `version` is supported by a `VersionMap`.
71+
pub trait VersionFilter: Debug {
72+
/// Check whether the `version` is supported or not.
73+
fn is_supported(&self, version: u16) -> bool;
74+
}
75+
76+
impl VersionFilter for () {
77+
fn is_supported(&self, _version: u16) -> bool {
78+
true
79+
}
80+
}
6881
///
6982
/// The VersionMap API provides functionality to define the version for each
7083
/// type and attach them to specific root versions.
71-
#[derive(Clone, Debug, Default)]
84+
#[derive(Clone, Debug)]
7285
pub struct VersionMap {
7386
versions: Vec<HashMap<TypeId, u16>>,
87+
filter: Arc<dyn VersionFilter>,
88+
}
89+
90+
impl Default for VersionMap {
91+
fn default() -> Self {
92+
VersionMap {
93+
versions: vec![HashMap::new(); 1],
94+
filter: Arc::new(()),
95+
}
96+
}
7497
}
7598

7699
impl VersionMap {
77100
/// Create a new version map initialized at version 1.
78101
pub fn new() -> Self {
102+
Default::default()
103+
}
104+
105+
/// Create a new version map with specified version filter.
106+
pub fn with_filter(filter: Arc<dyn VersionFilter>) -> Self {
79107
VersionMap {
80108
versions: vec![HashMap::new(); 1],
109+
filter,
81110
}
82111
}
83112

@@ -119,16 +148,36 @@ impl VersionMap {
119148
pub fn latest_version(&self) -> u16 {
120149
self.versions.len() as u16
121150
}
151+
152+
/// Check whether the `version` is supported by the version map.
153+
pub fn is_supported(&self, version: u16) -> bool {
154+
if version == 0 || version > self.latest_version() {
155+
false
156+
} else {
157+
self.filter.is_supported(version)
158+
}
159+
}
122160
}
123161

124162
#[cfg(test)]
125163
mod tests {
126164
use super::{TypeId, VersionMap, BASE_VERSION};
165+
use std::sync::Arc;
166+
use version_map::VersionFilter;
127167

128168
pub struct MyType;
129169
pub struct MySecondType;
130170
pub struct MyThirdType;
131171

172+
#[derive(Debug)]
173+
struct MyFilter;
174+
175+
impl VersionFilter for MyFilter {
176+
fn is_supported(&self, version: u16) -> bool {
177+
version < 5
178+
}
179+
}
180+
132181
#[test]
133182
fn test_default_version() {
134183
let vm = VersionMap::new();
@@ -223,4 +272,32 @@ mod tests {
223272
assert_eq!(vm.get_type_version(129, TypeId::of::<MyType>()), 2);
224273
assert_eq!(vm.get_type_version(1, TypeId::of::<MyType>()), BASE_VERSION);
225274
}
275+
276+
#[test]
277+
fn test_version_filter() {
278+
let mut vm = VersionMap::default();
279+
vm.new_version();
280+
281+
assert_eq!(vm.is_supported(0), false);
282+
assert_eq!(vm.is_supported(1), true);
283+
assert_eq!(vm.is_supported(2), true);
284+
assert_eq!(vm.is_supported(3), false);
285+
286+
let mut vm = VersionMap::with_filter(Arc::new(MyFilter));
287+
vm.new_version();
288+
vm.new_version();
289+
vm.new_version();
290+
vm.new_version();
291+
vm.new_version();
292+
293+
let vm1 = vm.clone();
294+
assert_eq!(vm1.is_supported(0), false);
295+
assert_eq!(vm1.is_supported(1), true);
296+
assert_eq!(vm1.is_supported(2), true);
297+
assert_eq!(vm1.is_supported(3), true);
298+
assert_eq!(vm1.is_supported(4), true);
299+
assert_eq!(vm1.is_supported(5), false);
300+
assert_eq!(vm1.is_supported(6), false);
301+
assert_eq!(vm.latest_version(), 6);
302+
}
226303
}

0 commit comments

Comments
 (0)