robotrt-data-model 0.1.0-beta.1

RobotRT modular robotics runtime and middleware components.
Documentation
use std::collections::HashMap;

use core_types::{ErrorCode, ErrorDomain, RtError};

use crate::compat::CompatibilityPolicy;
use crate::schema::{SchemaDescriptor, SchemaId, SchemaVersion};

pub trait SchemaRegistry {
    fn register(&mut self, descriptor: SchemaDescriptor) -> Result<(), RtError>;
    fn get(&self, id: &SchemaId) -> Option<&SchemaDescriptor>;
    fn is_compatible(
        &self,
        id: &SchemaId,
        version: SchemaVersion,
        policy: CompatibilityPolicy,
    ) -> bool;
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct CodecDescriptor {
    pub schema_id: SchemaId,
    pub name: String,
    pub zero_copy: bool,
}

pub trait CodecRegistry {
    fn register(&mut self, descriptor: CodecDescriptor) -> Result<(), RtError>;
    fn get(&self, schema_id: &SchemaId) -> Option<&CodecDescriptor>;
}

#[derive(Default)]
pub struct SimpleSchemaRegistry {
    schemas: HashMap<SchemaId, SchemaDescriptor>,
}

impl SchemaRegistry for SimpleSchemaRegistry {
    fn register(&mut self, descriptor: SchemaDescriptor) -> Result<(), RtError> {
        if self.schemas.contains_key(&descriptor.id) {
            return Err(RtError::new(
                ErrorCode::InvalidState,
                ErrorDomain::DataModel,
                false,
                "schema already registered",
            ));
        }
        self.schemas.insert(descriptor.id.clone(), descriptor);
        Ok(())
    }

    fn get(&self, id: &SchemaId) -> Option<&SchemaDescriptor> {
        self.schemas.get(id)
    }

    fn is_compatible(
        &self,
        id: &SchemaId,
        version: SchemaVersion,
        policy: CompatibilityPolicy,
    ) -> bool {
        self.get(id)
            .map(|descriptor| policy.check(descriptor.version, version))
            .unwrap_or(false)
    }
}

#[derive(Default)]
pub struct SimpleCodecRegistry {
    codecs: HashMap<SchemaId, CodecDescriptor>,
}

impl CodecRegistry for SimpleCodecRegistry {
    fn register(&mut self, descriptor: CodecDescriptor) -> Result<(), RtError> {
        if self.codecs.contains_key(&descriptor.schema_id) {
            return Err(RtError::new(
                ErrorCode::InvalidState,
                ErrorDomain::DataModel,
                false,
                "codec already registered",
            ));
        }
        self.codecs.insert(descriptor.schema_id.clone(), descriptor);
        Ok(())
    }

    fn get(&self, schema_id: &SchemaId) -> Option<&CodecDescriptor> {
        self.codecs.get(schema_id)
    }
}