use crate::rr::rdata::CERT;
use crate::rr::rdata::cert::{Algorithm, CertType};
use crate::serialize::txt::errors::{ParseError, ParseErrorKind, ParseResult};
fn to_u16(data: &str) -> ParseResult<u16> {
data.parse().map_err(ParseError::from)
}
fn to_u8(data: &str) -> ParseResult<u8> {
data.parse().map_err(ParseError::from)
}
pub(crate) fn parse<'i, I: Iterator<Item = &'i str>>(tokens: I) -> ParseResult<CERT> {
let mut iter = tokens;
let token = iter
.next()
.ok_or_else(|| ParseError::from(ParseErrorKind::Message("CERT cert type field missing")))?;
let cert_type = CertType::from(to_u16(token).map_err(|_| {
ParseError::from(ParseErrorKind::Message(
"Invalid digit found in cert_type token",
))
})?);
let token = iter
.next()
.ok_or_else(|| ParseError::from(ParseErrorKind::Message("CERT key tag field missing")))?;
let key_tag = to_u16(token).map_err(|_| {
ParseError::from(ParseErrorKind::Message(
"Invalid digit found in key_tag token",
))
})?;
let token = iter
.next()
.ok_or_else(|| ParseError::from(ParseErrorKind::Message("CERT algorithm field missing")))?;
let algorithm = Algorithm::from(to_u8(token).map_err(|_| {
ParseError::from(ParseErrorKind::Message(
"Invalid digit found in algorithm token",
))
})?);
let token = iter
.next()
.ok_or_else(|| ParseError::from(ParseErrorKind::Message("CERT data missing")))?;
let cert_data = data_encoding::BASE64
.decode(token.as_bytes())
.map_err(|_| ParseError::from(ParseErrorKind::Message("Invalid base64 CERT data")))?;
Ok(CERT::new(cert_type, key_tag, algorithm, cert_data))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_valid_cert_data() {
let tokens = vec!["1", "123", "3", "Q2VydGlmaWNhdGUgZGF0YQ=="].into_iter();
let result = parse(tokens);
assert!(result.is_ok());
let cert = result.unwrap();
assert_eq!(cert.cert_type(), CertType::from(1));
assert_eq!(cert.key_tag(), 123);
assert_eq!(cert.algorithm(), Algorithm::from(3));
assert_eq!(cert.cert_data(), b"Certificate data".to_vec()); }
#[test]
fn test_invalid_base64_data() {
let tokens = vec!["1", "123", "3", "Invalid_base64"].into_iter();
let result = parse(tokens);
assert!(result.is_err());
let err = result.unwrap_err();
assert_eq!(format!("{}", err), "Invalid base64 CERT data");
}
#[test]
fn test_invalid_token_digit() {
let tokens = vec!["123", "3", "Q2VydGlmaWNhdGUgZGF0YQ=="].into_iter();
let result = parse(tokens);
assert!(result.is_err());
let err = result.unwrap_err();
assert_eq!(format!("{}", err), "Invalid digit found in algorithm token");
}
#[test]
fn test_missing_cert_data() {
let tokens = vec!["1", "123", "3"].into_iter();
let result = parse(tokens);
assert!(result.is_err());
let err = result.unwrap_err();
assert_eq!(format!("{}", err), "CERT data missing");
}
}