rasn-compiler 0.16.0

An ASN.1 compiler producing bindings for the rasn framework
Documentation
use std::collections::BTreeMap;

use crate::intermediate::{constraints::*, error::*, *};

impl Constraint {
    pub(super) fn link_cross_reference(
        &mut self,
        identifier: &String,
        tlds: &BTreeMap<String, ToplevelDefinition>,
    ) -> Result<(), GrammarError> {
        match self {
            Constraint::Subtype(t) => t.set.link_cross_reference(identifier, tlds),
            _ => Ok(()),
        }
    }

    pub(super) fn has_cross_reference(&self) -> bool {
        match self {
            Self::Subtype(c) => c.set.has_cross_reference(),
            Self::Parameter(_) => true,
            _ => false,
        }
    }
}

impl SubtypeElements {
    pub(super) fn link_cross_reference(
        &mut self,
        identifier: &String,
        tlds: &BTreeMap<String, ToplevelDefinition>,
    ) -> Result<(), GrammarError> {
        match self {
            SubtypeElements::SingleValue {
                value,
                extensible: _,
            } => {
                value.link_elsewhere_declared(identifier, tlds)?;
            }
            SubtypeElements::PermittedAlphabet(e) => {
                e.link_cross_reference(identifier, tlds)?;
            }
            SubtypeElements::ContainedSubtype {
                subtype,
                extensible: _,
            } => {
                subtype.link_subtype_constraint(tlds)?;
            }
            SubtypeElements::ValueRange {
                min,
                max,
                extensible: _,
            } => {
                min.as_mut()
                    .map(|m| m.link_elsewhere_declared(identifier, tlds))
                    .transpose()?;
                max.as_mut()
                    .map(|m| m.link_elsewhere_declared(identifier, tlds))
                    .transpose()?;
            }
            SubtypeElements::SizeConstraint(s) => {
                s.link_cross_reference(identifier, tlds)?;
            }
            SubtypeElements::TypeConstraint(t) => {
                t.link_constraint_reference(identifier, tlds)?;
            }
            SubtypeElements::SingleTypeConstraint(constraints) => {
                for c in constraints {
                    c.link_cross_reference(identifier, tlds)?;
                }
            }
            SubtypeElements::MultipleTypeConstraints(s) => {
                for b in s.constraints.iter_mut().flat_map(|cc| &mut cc.constraints) {
                    b.link_cross_reference(identifier, tlds)?;
                }
            }
            _ => (),
        }
        Ok(())
    }

    pub(super) fn has_cross_reference(&self) -> bool {
        match self {
            SubtypeElements::SingleValue {
                value,
                extensible: _,
            } => value.is_elsewhere_declared(),
            SubtypeElements::PatternConstraint(_) => false,
            SubtypeElements::UserDefinedConstraint(_) => false,
            SubtypeElements::PropertySettings(_) => false,
            SubtypeElements::PermittedAlphabet(e) => e.has_cross_reference(),
            SubtypeElements::ContainedSubtype {
                subtype,
                extensible: _,
            } => subtype.contains_constraint_reference(),
            SubtypeElements::ValueRange {
                min,
                max,
                extensible: _,
            } => {
                min.as_ref().is_some_and(|s| s.is_elsewhere_declared())
                    || max.as_ref().is_some_and(|s| s.is_elsewhere_declared())
            }
            SubtypeElements::SizeConstraint(s) => s.has_cross_reference(),
            SubtypeElements::TypeConstraint(t) => t.references_class_by_name(),
            SubtypeElements::SingleTypeConstraint(c) => {
                c.iter().any(|constraint| constraint.has_cross_reference())
            }
            SubtypeElements::MultipleTypeConstraints(s) => s
                .constraints
                .iter()
                .any(|cc| cc.constraints.iter().any(|c| c.has_cross_reference())),
        }
    }
}

impl ElementOrSetOperation {
    pub(super) fn link_cross_reference(
        &mut self,
        identifier: &String,
        tlds: &BTreeMap<String, ToplevelDefinition>,
    ) -> Result<(), GrammarError> {
        match self {
            ElementOrSetOperation::Element(e) => e.link_cross_reference(identifier, tlds),
            ElementOrSetOperation::SetOperation(s) => {
                s.base.link_cross_reference(identifier, tlds)?;
                s.operant.link_cross_reference(identifier, tlds)
            }
        }
    }

    pub(super) fn has_cross_reference(&self) -> bool {
        match self {
            ElementOrSetOperation::Element(e) => e.has_cross_reference(),
            ElementOrSetOperation::SetOperation(s) => {
                s.base.has_cross_reference() || s.operant.has_cross_reference()
            }
        }
    }
}