use crate::{
input::Input,
intermediate::{ASN1Type, ObjectIdentifierArc, ObjectIdentifierValue, OBJECT_IDENTIFIER},
};
use nom::{
branch::alt,
bytes::complete::tag,
character::complete::u128,
combinator::{into, map, opt},
multi::many1,
sequence::{pair, preceded},
Parser,
};
use super::{
common::{in_braces, in_parentheses, skip_ws, skip_ws_and_comments, value_reference},
constraint::constraints,
error::ParserResult,
RELATIVE_OID,
};
pub fn object_identifier_value(input: Input<'_>) -> ParserResult<'_, ObjectIdentifierValue> {
into(skip_ws_and_comments(preceded(
opt(alt((tag(OBJECT_IDENTIFIER), tag(RELATIVE_OID)))),
in_braces(many1(skip_ws(object_identifier_arc))),
)))
.parse(input)
}
pub fn object_identifier(input: Input<'_>) -> ParserResult<'_, ASN1Type> {
map(
into(preceded(
skip_ws_and_comments(alt((tag(OBJECT_IDENTIFIER), tag(RELATIVE_OID)))),
opt(skip_ws_and_comments(constraints)),
)),
ASN1Type::ObjectIdentifier,
)
.parse(input)
}
fn object_identifier_arc(input: Input<'_>) -> ParserResult<'_, ObjectIdentifierArc> {
skip_ws(alt((
numeric_id,
into(pair(value_reference, skip_ws(in_parentheses(u128)))),
into(value_reference),
)))
.parse(input)
}
fn numeric_id(input: Input<'_>) -> ParserResult<'_, ObjectIdentifierArc> {
map(u128, |i| i.into()).parse(input)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parses_ansi_x9_62() {
assert_eq!(
object_identifier_value(r#"{iso(1) member-body(2) us(840) 10045 modules(0) 2}"#.into())
.unwrap()
.1,
ObjectIdentifierValue(vec![
ObjectIdentifierArc {
name: Some("iso".into()),
number: Some(1)
},
ObjectIdentifierArc {
name: Some("member-body".into()),
number: Some(2)
},
ObjectIdentifierArc {
name: Some("us".into()),
number: Some(840)
},
ObjectIdentifierArc {
name: None,
number: Some(10045)
},
ObjectIdentifierArc {
name: Some("modules".into()),
number: Some(0)
},
ObjectIdentifierArc {
name: None,
number: Some(2)
},
])
)
}
}