2020-01-10 18:20:30 +01:00
|
|
|
use std::collections::HashMap;
|
2020-02-26 17:34:26 +01:00
|
|
|
use std::collections::hash_map::Iter;
|
2020-01-10 18:20:30 +01:00
|
|
|
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
2020-01-13 19:10:58 +01:00
|
|
|
use crate::{SResult, FieldId};
|
2020-01-10 18:20:30 +01:00
|
|
|
|
|
|
|
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
|
|
pub struct FieldsMap {
|
|
|
|
name_map: HashMap<String, FieldId>,
|
|
|
|
id_map: HashMap<FieldId, String>,
|
|
|
|
next_id: FieldId
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FieldsMap {
|
|
|
|
pub fn len(&self) -> usize {
|
|
|
|
self.name_map.len()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
|
|
self.name_map.is_empty()
|
|
|
|
}
|
|
|
|
|
2020-01-29 18:30:21 +01:00
|
|
|
pub fn insert(&mut self, name: &str) -> SResult<FieldId> {
|
|
|
|
if let Some(id) = self.name_map.get(name) {
|
2020-01-10 18:20:30 +01:00
|
|
|
return Ok(*id)
|
|
|
|
}
|
2020-02-02 22:59:19 +01:00
|
|
|
let id = self.next_id;
|
2020-01-10 18:20:30 +01:00
|
|
|
self.next_id = self.next_id.next()?;
|
2020-01-29 18:30:21 +01:00
|
|
|
self.name_map.insert(name.to_string(), id);
|
|
|
|
self.id_map.insert(id, name.to_string());
|
2020-01-10 18:20:30 +01:00
|
|
|
Ok(id)
|
|
|
|
}
|
|
|
|
|
2020-01-29 18:30:21 +01:00
|
|
|
pub fn remove(&mut self, name: &str) {
|
|
|
|
if let Some(id) = self.name_map.get(name) {
|
2020-01-10 18:20:30 +01:00
|
|
|
self.id_map.remove(&id);
|
|
|
|
}
|
2020-01-29 18:30:21 +01:00
|
|
|
self.name_map.remove(name);
|
2020-01-10 18:20:30 +01:00
|
|
|
}
|
|
|
|
|
2020-01-29 18:30:21 +01:00
|
|
|
pub fn id(&self, name: &str) -> Option<FieldId> {
|
2020-02-02 22:59:19 +01:00
|
|
|
self.name_map.get(name).copied()
|
2020-01-10 18:20:30 +01:00
|
|
|
}
|
|
|
|
|
2020-01-29 18:30:21 +01:00
|
|
|
pub fn name<I: Into<FieldId>>(&self, id: I) -> Option<&str> {
|
|
|
|
self.id_map.get(&id.into()).map(|s| s.as_str())
|
2020-01-10 18:20:30 +01:00
|
|
|
}
|
2020-02-26 17:34:26 +01:00
|
|
|
|
|
|
|
pub fn iter(&self) -> Iter<'_, String, FieldId> {
|
|
|
|
self.name_map.iter()
|
|
|
|
}
|
2020-01-10 18:20:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn fields_map() {
|
|
|
|
let mut fields_map = FieldsMap::default();
|
|
|
|
assert_eq!(fields_map.insert("id").unwrap(), 0.into());
|
|
|
|
assert_eq!(fields_map.insert("title").unwrap(), 1.into());
|
|
|
|
assert_eq!(fields_map.insert("descritpion").unwrap(), 2.into());
|
|
|
|
assert_eq!(fields_map.insert("id").unwrap(), 0.into());
|
|
|
|
assert_eq!(fields_map.insert("title").unwrap(), 1.into());
|
|
|
|
assert_eq!(fields_map.insert("descritpion").unwrap(), 2.into());
|
2020-01-29 18:30:21 +01:00
|
|
|
assert_eq!(fields_map.id("id"), Some(0.into()));
|
|
|
|
assert_eq!(fields_map.id("title"), Some(1.into()));
|
|
|
|
assert_eq!(fields_map.id("descritpion"), Some(2.into()));
|
|
|
|
assert_eq!(fields_map.id("date"), None);
|
2020-01-10 18:20:30 +01:00
|
|
|
assert_eq!(fields_map.len(), 3);
|
2020-01-29 18:30:21 +01:00
|
|
|
assert_eq!(fields_map.name(0), Some("id"));
|
|
|
|
assert_eq!(fields_map.name(1), Some("title"));
|
|
|
|
assert_eq!(fields_map.name(2), Some("descritpion"));
|
|
|
|
assert_eq!(fields_map.name(4), None);
|
2020-01-10 18:20:30 +01:00
|
|
|
fields_map.remove("title");
|
2020-01-29 18:30:21 +01:00
|
|
|
assert_eq!(fields_map.id("title"), None);
|
2020-01-10 18:20:30 +01:00
|
|
|
assert_eq!(fields_map.insert("title").unwrap(), 3.into());
|
|
|
|
assert_eq!(fields_map.len(), 3);
|
|
|
|
}
|
|
|
|
}
|