use std::collections::HashMap;
use std::sync::{Arc, Mutex};
#[derive(Clone)]
pub struct SchemaCache(Arc<Mutex<HashMap<String, Option<String>>>>);
impl SchemaCache {
pub fn new() -> Self {
Self(Arc::new(Mutex::new(HashMap::new())))
}
pub fn push(&self, pointer: &str, content: Option<&str>) -> bool {
let mut map = self.0.lock().unwrap();
if let Some(existing) = map.get(pointer) {
if existing.is_none() {
map.insert(pointer.to_string(), content.map(|c| c.to_string()));
}
false
} else {
map.insert(pointer.to_string(), content.map(|c| c.to_string()));
true
}
}
pub fn drain(&self) -> HashMap<String, Option<String>> {
let mut map = self.0.lock().unwrap();
let mut drained = HashMap::new();
for (key, value) in map.iter_mut() {
if let Some(v) = value.take() {
drained.insert(key.clone(), Some(v));
}
}
drained
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_push_and_drain() {
let cache = SchemaCache::new();
assert!(cache.push("#/components/schemas/Pet", None));
assert!(!cache.push("#/components/schemas/Pet", Some("struct Pet{}")));
assert!(!cache.push("#/components/schemas/Pet", Some("struct Pet2{}")));
let drained = cache.drain();
assert_eq!(drained.len(), 1);
assert_eq!(
drained.get("#/components/schemas/Pet"),
Some(&Some("struct Pet{}".to_string()))
);
let drained2 = cache.drain();
assert!(drained2.is_empty());
}
}