Jeff Baskin 115910120c
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 1s
Moved Oid into document module.
2026-02-13 12:48:17 -05:00

205 lines
4.2 KiB
Rust

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<Oid> = 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<Uuid, Field>,
}
impl InternalRecord {
pub fn new() -> Self {
Self {
data: HashMap::new(),
}
}
pub fn insert<F>(&mut self, id: Uuid, data: F) -> Field
where
F: Into<Field>,
{
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<Oid, InternalRecord>,
}
impl InternalRecords {
pub fn new() -> Self {
Self {
data: HashMap::new(),
}
}
pub fn insert(&mut self, oid: Oid, record: InternalRecord) -> Option<InternalRecord> {
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<InternalRecord> {
self.data.remove(oid)
}
pub fn iter(&self) -> impl Iterator<Item = (&Oid, &InternalRecord)> {
self.data.iter()
}
pub fn keys(&self) -> impl Iterator<Item = &Oid> {
self.data.keys()
}
pub fn values(&self) -> impl Iterator<Item = &InternalRecord> {
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<NT>(&self, field_id: NT) -> Result<Field, MTTError>
where
NT: Into<NameType>,
{
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<InternalRecord> {
self.data.insert(oid, record)
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn iter(&self) -> impl Iterator<Item = Record> {
RecordIter::new(self)
}
pub fn get_internal_records(&self) -> &InternalRecords {
&self.data
}
}
struct RecordIter {
names: Names,
recs: Vec<InternalRecord>,
}
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<Self::Item> {
match self.recs.pop() {
Some(rec) => Some(Record::with_data(self.names.clone(), rec.clone())),
None => None,
}
}
}