rl_model-rs 0.2.2

'Robot Language' parser and rust model
Documentation
use super::*;
use crate::parser::*;
use std::collections::HashMap;

#[derive(Debug, Clone)]
pub enum Expr {
    True,
    False,
    ResourceEq(Reference<ResourceId>, Reference<StateId>),
    ResourceNe(Reference<ResourceId>, Reference<StateId>),
    Not(Box<Expr>),
    And(Box<Expr>, Box<Expr>),
    Or(Box<Expr>, Box<Expr>),
    Implies(Box<Expr>, Box<Expr>),
}

impl Expr {
    pub fn resolve_resource(&mut self, map: &HashMap<String, ResourceId>) -> Result<(), RlError> {
        match self {
            Expr::True => Ok(()),
            Expr::False => Ok(()),
            Expr::ResourceEq(resource, _) => match resource {
                Reference::Unresolved(name, pos) => match map.get(name) {
                    Some(id) => {
                        *resource = Reference::Resolved(*id);
                        Ok(())
                    }
                    None => Err(RlError::Resolve {
                        element: format!("resource '{}'", name),
                        position: pos.clone(),
                    }),
                },
                Reference::Resolved(_) => Ok(()),
            },
            Expr::ResourceNe(resource, _) => match resource {
                Reference::Unresolved(name, pos) => match map.get(name) {
                    Some(id) => {
                        *resource = Reference::Resolved(*id);
                        Ok(())
                    }
                    None => Err(RlError::Resolve {
                        element: format!("resource '{}'", name),
                        position: pos.clone(),
                    }),
                },
                Reference::Resolved(_) => Ok(()),
            },
            Expr::Not(e) => e.resolve_resource(map),
            Expr::And(l, r) => {
                l.resolve_resource(map)?;
                r.resolve_resource(map)
            }
            Expr::Or(l, r) => {
                l.resolve_resource(map)?;
                r.resolve_resource(map)
            }
            Expr::Implies(l, r) => {
                l.resolve_resource(map)?;
                r.resolve_resource(map)
            }
        }
    }

    pub fn resolve_state(&mut self, map: &HashMap<String, StateId>) -> Result<(), RlError> {
        match self {
            Expr::True => Ok(()),
            Expr::False => Ok(()),
            Expr::ResourceEq(_, state) => match state {
                Reference::Unresolved(name, pos) => match map.get(name) {
                    Some(id) => {
                        *state = Reference::Resolved(*id);
                        Ok(())
                    }
                    None => Err(RlError::Resolve {
                        element: format!("state '{}'", name),
                        position: pos.clone(),
                    }),
                },
                Reference::Resolved(_) => Ok(()),
            },
            Expr::ResourceNe(_, state) => match state {
                Reference::Unresolved(name, pos) => match map.get(name) {
                    Some(id) => {
                        *state = Reference::Resolved(*id);
                        Ok(())
                    }
                    None => Err(RlError::Resolve {
                        element: format!("state '{}'", name),
                        position: pos.clone(),
                    }),
                },
                Reference::Resolved(_) => Ok(()),
            },
            Expr::Not(e) => e.resolve_state(map),
            Expr::And(l, r) => {
                l.resolve_state(map)?;
                r.resolve_state(map)
            }
            Expr::Or(l, r) => {
                l.resolve_state(map)?;
                r.resolve_state(map)
            }
            Expr::Implies(l, r) => {
                l.resolve_state(map)?;
                r.resolve_state(map)
            }
        }
    }
}

impl ToLang for Expr {
    fn to_lang(&self, skillset: &Skillset) -> String {
        match self {
            Expr::True => String::from("true"),
            Expr::False => String::from("false"),
            Expr::ResourceEq(resource, state) => {
                format!(
                    "{} == {}",
                    resource.to_lang(skillset),
                    state.to_lang(skillset)
                )
            }
            Expr::ResourceNe(resource, state) => {
                format!(
                    "{} != {}",
                    resource.to_lang(skillset),
                    state.to_lang(skillset)
                )
            }
            Expr::Not(e) => format!("(not {})", e.to_lang(skillset)),
            Expr::And(l, r) => format!("({} and {})", l.to_lang(skillset), r.to_lang(skillset)),
            Expr::Or(l, r) => format!("({} or {})", l.to_lang(skillset), r.to_lang(skillset)),
            Expr::Implies(l, r) => format!("({} => {})", l.to_lang(skillset), r.to_lang(skillset)),
        }
    }
}