use nom::{
bytes::complete::tag,
combinator::{map, opt},
sequence::preceded,
Parser,
};
use crate::{input::Input, intermediate::*};
use super::{common::*, constraint::constraints, error::ParserResult};
pub fn octet_string(input: Input<'_>) -> ParserResult<'_, ASN1Type> {
map(
preceded(skip_ws_and_comments(tag(OCTET_STRING)), opt(constraints)),
|m| ASN1Type::OctetString(m.into()),
)
.parse(input)
}
#[cfg(test)]
mod tests {
use crate::intermediate::{constraints::*, types::*, *};
use super::octet_string;
#[test]
fn parses_unconfined_octetstring() {
let sample = " OCTET STRING".into();
assert_eq!(
octet_string(sample).unwrap().1,
ASN1Type::OctetString(OctetString {
constraints: vec![]
})
)
}
#[test]
fn parses_strictly_constrained_octetstring() {
let sample = " OCTET STRING(SIZE (8))".into();
assert_eq!(
octet_string(sample).unwrap().1,
ASN1Type::OctetString(OctetString {
constraints: vec![Constraint::Subtype(ElementSetSpecs {
set: ElementOrSetOperation::Element(SubtypeElements::SizeConstraint(Box::new(
ElementOrSetOperation::Element(SubtypeElements::SingleValue {
value: ASN1Value::Integer(8),
extensible: false
})
))),
extensible: false
})]
})
)
}
#[test]
fn parses_range_constrained_octetstring() {
let sample = " OCTET STRING -- even here?!?!? -- (SIZE (8 ..18))".into();
assert_eq!(
octet_string(sample).unwrap().1,
ASN1Type::OctetString(OctetString {
constraints: vec![Constraint::Subtype(ElementSetSpecs {
set: ElementOrSetOperation::Element(SubtypeElements::SizeConstraint(Box::new(
ElementOrSetOperation::Element(SubtypeElements::ValueRange {
min: Some(ASN1Value::Integer(8)),
max: Some(ASN1Value::Integer(18)),
extensible: false
})
))),
extensible: false
})]
})
)
}
#[test]
fn parses_strictly_constrained_extended_octetstring() {
let sample = " OCTET STRING (SIZE (2, ...))".into();
assert_eq!(
octet_string(sample).unwrap().1,
ASN1Type::OctetString(OctetString {
constraints: vec![Constraint::Subtype(ElementSetSpecs {
set: ElementOrSetOperation::Element(SubtypeElements::SizeConstraint(Box::new(
ElementOrSetOperation::Element(SubtypeElements::SingleValue {
value: ASN1Value::Integer(2),
extensible: true
})
))),
extensible: false
})]
})
)
}
#[test]
fn parses_range_constrained_extended_octetstring() {
let sample = " OCTET STRING (SIZE (8 -- comment -- .. 18, ...))".into();
assert_eq!(
octet_string(sample).unwrap().1,
ASN1Type::OctetString(OctetString {
constraints: vec![Constraint::Subtype(ElementSetSpecs {
set: ElementOrSetOperation::Element(SubtypeElements::SizeConstraint(Box::new(
ElementOrSetOperation::Element(SubtypeElements::ValueRange {
min: Some(ASN1Value::Integer(8)),
max: Some(ASN1Value::Integer(18)),
extensible: true
})
))),
extensible: false
})]
})
)
}
}