use std::fmt;
#[derive(Debug, Clone, PartialEq)]
pub enum TaggingMode {
Explicit,
Implicit,
Automatic,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Module {
pub name: String,
pub oid: Option<Vec<String>>,
pub tagging_mode: Option<TaggingMode>,
pub imports: Vec<Import>,
pub exports: Vec<String>,
pub definitions: Vec<Definition>,
pub values: Vec<ValueAssignment>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Import {
pub symbols: Vec<String>,
pub module_name: String,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Definition {
pub name: String,
pub ty: Type,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ValueAssignment {
pub name: String,
pub ty: Type,
pub value: Value,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Value {
ObjectIdentifier(Vec<OidComponent>),
Integer(i64),
Boolean(bool),
String(String),
}
#[derive(Debug, Clone, PartialEq)]
pub enum OidComponent {
Number(u32),
NamedRef(String),
}
#[derive(Debug, Clone, PartialEq)]
pub struct NamedNumber {
pub name: String,
pub value: i64,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ClassField {
pub name: String,
pub unique: bool,
pub optional: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Type {
Sequence(Vec<SequenceField>),
SequenceOf(Box<Type>, Option<SizeConstraint>),
Set(Vec<SequenceField>),
SetOf(Box<Type>, Option<SizeConstraint>),
Choice(Vec<ChoiceVariant>),
TypeRef(String),
Integer(Option<ValueConstraint>, Vec<NamedNumber>),
Enumerated(Vec<NamedNumber>),
Real,
Boolean,
OctetString(Option<SizeConstraint>),
BitString(Option<SizeConstraint>),
ObjectIdentifier,
Null,
Utf8String(Option<SizeConstraint>),
PrintableString(Option<SizeConstraint>),
IA5String(Option<SizeConstraint>),
TeletexString(Option<SizeConstraint>),
UniversalString(Option<SizeConstraint>),
BmpString(Option<SizeConstraint>),
GeneralString(Option<SizeConstraint>),
NumericString(Option<SizeConstraint>),
VisibleString(Option<SizeConstraint>),
UtcTime,
GeneralizedTime,
Tagged { tag: TagInfo, inner: Box<Type> },
Constrained {
base_type: Box<Type>,
constraint: Constraint,
},
Any,
AnyDefinedBy(String),
Class(Vec<ClassField>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct Constraint {
pub spec: ConstraintSpec,
pub exception: Option<ExceptionSpec>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ConstraintSpec {
Subtype(SubtypeConstraint),
General(GeneralConstraint),
}
#[derive(Debug, Clone, PartialEq)]
pub enum SubtypeConstraint {
SingleValue(ConstraintValue),
ValueRange {
min: ConstraintValue,
max: ConstraintValue,
},
SizeConstraint(Box<SubtypeConstraint>),
PermittedAlphabet(Vec<CharRange>),
Pattern(String),
ContainedSubtype(Box<Type>),
InnerType(Box<SubtypeConstraint>),
Union(Vec<SubtypeConstraint>),
Intersection(Vec<SubtypeConstraint>),
Complement(Box<SubtypeConstraint>),
NamedBitList(Vec<NamedNumber>),
}
#[derive(Debug, Clone, PartialEq)]
pub enum ConstraintValue {
Integer(i64),
NamedValue(String),
Min,
Max,
}
#[derive(Debug, Clone, PartialEq)]
pub struct CharRange {
pub min: char,
pub max: char,
}
#[derive(Debug, Clone, PartialEq)]
pub enum GeneralConstraint {
ComponentRelation {
object_set: String,
component_refs: Vec<String>,
},
UserDefined(String),
}
#[derive(Debug, Clone, PartialEq)]
pub enum ExceptionSpec {
Identifier(String),
Value(ConstraintValue),
}
#[derive(Debug, Clone, PartialEq)]
pub enum ValueConstraint {
Single(i64),
Range(Option<i64>, Option<i64>),
}
#[derive(Debug, Clone, PartialEq)]
pub enum SizeConstraint {
Fixed(u64),
Range(Option<u64>, Option<u64>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct SequenceField {
pub name: String,
pub ty: Type,
pub optional: bool,
pub default: Option<String>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ChoiceVariant {
pub name: String,
pub ty: Type,
}
#[derive(Debug, Clone, PartialEq)]
pub struct TagInfo {
pub class: TagClass,
pub number: u32,
pub tagging: Tagging,
}
#[derive(Debug, Clone, PartialEq)]
pub enum TagClass {
Universal,
Application,
ContextSpecific,
Private,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Tagging {
Explicit,
Implicit,
}
impl fmt::Display for Type {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Type::Sequence(_) => write!(f, "SEQUENCE"),
Type::SequenceOf(inner, _) => write!(f, "SEQUENCE OF {}", inner),
Type::Set(_) => write!(f, "SET"),
Type::SetOf(inner, _) => write!(f, "SET OF {}", inner),
Type::Choice(_) => write!(f, "CHOICE"),
Type::TypeRef(name) => write!(f, "{}", name),
Type::Integer(_, _) => write!(f, "INTEGER"),
Type::Enumerated(_) => write!(f, "ENUMERATED"),
Type::Real => write!(f, "REAL"),
Type::Boolean => write!(f, "BOOLEAN"),
Type::OctetString(_) => write!(f, "OCTET STRING"),
Type::BitString(_) => write!(f, "BIT STRING"),
Type::ObjectIdentifier => write!(f, "OBJECT IDENTIFIER"),
Type::Null => write!(f, "NULL"),
Type::Utf8String(_) => write!(f, "UTF8String"),
Type::PrintableString(_) => write!(f, "PrintableString"),
Type::IA5String(_) => write!(f, "IA5String"),
Type::TeletexString(_) => write!(f, "TeletexString"),
Type::UniversalString(_) => write!(f, "UniversalString"),
Type::BmpString(_) => write!(f, "BMPString"),
Type::GeneralString(_) => write!(f, "GeneralString"),
Type::NumericString(_) => write!(f, "NumericString"),
Type::VisibleString(_) => write!(f, "VisibleString"),
Type::UtcTime => write!(f, "UTCTime"),
Type::GeneralizedTime => write!(f, "GeneralizedTime"),
Type::Tagged { tag, inner } => {
write!(f, "[{}] {:?} {}", tag.number, tag.tagging, inner)
}
Type::Constrained { base_type, .. } => {
write!(f, "{} (constrained)", base_type)
}
Type::Any => write!(f, "ANY"),
Type::AnyDefinedBy(field) => write!(f, "ANY DEFINED BY {}", field),
Type::Class(fields) => {
write!(f, "CLASS {{ ")?;
for (i, field) in fields.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "&{}", field.name)?;
if field.unique {
write!(f, " UNIQUE")?;
}
if field.optional {
write!(f, " OPTIONAL")?;
}
}
write!(f, " }}")
}
}
}
}