rl_model-rs 0.2.2

'Robot Language' parser and rust model
Documentation
use super::*;
use crate::parser::{Position, RlError};
use std::collections::HashMap;
use std::time::Duration;

#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
pub struct DataId(pub usize);
impl Id for DataId {
    fn index(&self) -> usize {
        self.0
    }
}

#[derive(Debug, Clone)]
pub struct Data {
    id: DataId,
    name: String,
    rl_type: Reference<TypeId>,
    period: Option<Duration>,
    position: Option<Position>,
}

impl Data {
    pub fn new<S: Into<String>>(
        name: S,
        rl_type: Reference<TypeId>,
        period: Option<Duration>,
        position: Option<Position>,
    ) -> Self {
        let id = DataId::default();
        let name = name.into();
        Self {
            id,
            name,
            rl_type,
            period,
            position,
        }
    }

    pub fn rl_type(&self) -> &Reference<TypeId> {
        &self.rl_type
    }

    pub fn set_type(&mut self, id: TypeId) {
        self.rl_type = Reference::Resolved(id);
    }

    pub fn period(&self) -> Option<Duration> {
        self.period
    }

    //---------- Resolve ----------

    pub fn resolve_type(&mut self, map: &HashMap<String, TypeId>) -> Result<(), RlError> {
        match self.rl_type() {
            Reference::Unresolved(name, pos) => match map.get(name) {
                Some(id) => {
                    self.set_type(*id);
                    Ok(())
                }
                None => Err(RlError::Resolve {
                    element: format!("type '{}'", name),
                    position: pos.clone(),
                }),
            },
            Reference::Resolved(_) => Ok(()),
        }
    }
}

impl Named<DataId> for Data {
    fn id(&self) -> DataId {
        self.id
    }

    fn set_id(&mut self, id: DataId) {
        self.id = id;
    }

    fn name(&self) -> &str {
        &self.name
    }

    fn position(&self) -> Option<Position> {
        self.position.clone()
    }
}

impl ToLang for Data {
    fn to_lang(&self, skillset: &Skillset) -> String {
        match self.period {
            Some(period) => format!(
                "{}: {} period {} ms\n",
                self.name,
                self.rl_type.to_lang(skillset),
                period.as_millis()
            ),
            None => format!("{}: {}\n", self.name, self.rl_type.to_lang(skillset)),
        }
    }
}

impl std::fmt::Display for Data {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.name)
    }
}