use crate::{ action::Field, mtterror::{ErrorID, MTTError}, name::{Name, NameType, Names}, }; use std::collections::HashMap; use uuid::Uuid; #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct Oid { oid: Uuid, } impl Oid { pub fn new() -> Self { Self { oid: Uuid::new_v4(), } } } #[cfg(test)] mod oids { use super::*; #[test] fn are_oids_random() { let count = 10; let mut holder: Vec = Vec::new(); while holder.len() < count { let result = Oid::new(); assert!(!holder.contains(&result)); holder.push(result); } } } #[derive(Clone, Debug)] pub struct InternalRecord { data: HashMap, } impl InternalRecord { pub fn new() -> Self { Self { data: HashMap::new(), } } pub fn insert(&mut self, id: Uuid, data: F) -> Field where F: Into, { match self.data.insert(id, data.into()) { Some(data) => data.clone(), None => Field::None, } } pub fn get(&self, id: &Uuid) -> Option<&Field> { self.data.get(id) } pub fn is_empty(&self) -> bool { self.data.is_empty() } } #[derive(Clone, Debug)] pub struct InternalRecords { data: HashMap, } impl InternalRecords { pub fn new() -> Self { Self { data: HashMap::new(), } } pub fn insert(&mut self, oid: Oid, record: InternalRecord) -> Option { self.data.insert(oid, record) } pub fn get(&self, oid: &Oid) -> Option<&InternalRecord> { self.data.get(oid) } pub fn remove(&mut self, oid: &Oid) -> Option { self.data.remove(oid) } pub fn iter(&self) -> impl Iterator { self.data.iter() } pub fn keys(&self) -> impl Iterator { self.data.keys() } pub fn values(&self) -> impl Iterator { self.data.values() } pub fn contains_key(&self, oid: &Oid) -> bool { self.data.contains_key(oid) } pub fn len(&self) -> usize { self.data.len() } } #[derive(Clone, Debug)] pub struct Record { names: Names, data: InternalRecord, } impl Record { pub fn with_data(names: Names, rec: InternalRecord) -> Self { Self { names: names, data: rec, } } pub fn get(&self, field_id: NT) -> Result where NT: Into, { let id = match self.names.get_id(field_id) { Ok(data) => data, Err(err) => return Err(err), }; match self.data.get(&id) { Some(data) => Ok(data.clone()), None => Err(MTTError::new(NameType::None, ErrorID::FieldMissingData)), } } } #[derive(Clone, Debug)] pub struct Records { names: Names, data: InternalRecords, } impl Records { pub fn new(names: Names) -> Self { Self { names: names, data: InternalRecords::new(), } } pub fn with_data(names: Names, records: InternalRecords) -> Self { Self { names: names, data: records, } } pub fn insert(&mut self, oid: Oid, record: InternalRecord) -> Option { self.data.insert(oid, record) } pub fn len(&self) -> usize { self.data.len() } pub fn iter(&self) -> impl Iterator { RecordIter::new(self) } pub fn get_internal_records(&self) -> &InternalRecords { &self.data } } struct RecordIter { names: Names, recs: Vec, } impl RecordIter { fn new(records: &Records) -> Self { Self { names: records.names.clone(), recs: records.data.values().cloned().collect(), } } } impl Iterator for RecordIter { type Item = Record; fn next(&mut self) -> Option { match self.recs.pop() { Some(rec) => Some(Record::with_data(self.names.clone(), rec.clone())), None => None, } } }