diff --git a/cmpv2/src/poll.rs b/cmpv2/src/poll.rs index dce21d850..6136aa541 100644 --- a/cmpv2/src/poll.rs +++ b/cmpv2/src/poll.rs @@ -3,7 +3,8 @@ use alloc::vec::Vec; use der::asn1::Int; -use der::Sequence; +use der::{Sequence, ValueOrd}; +use x509_cert::impl_newtype; use crate::header::PkiFreeText; @@ -38,9 +39,23 @@ pub type PollReqContentId = Int; /// ``` /// /// [RFC 4210 Section 5.3.22]: https://www.rfc-editor.org/rfc/rfc4210#section-5.3.22 -#[derive(Clone, Debug, Eq, PartialEq, Sequence)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct PollRepContent<'a>(pub Vec>); + +impl_newtype!(PollRepContent<'a>, Vec>); + +impl<'a> core::ops::Index for PollRepContent<'a> { + type Output = PollRepContentInner<'a>; + + fn index(&self, index: usize) -> &Self::Output { + &self.0[index] + } +} + +/// The `PollRepContentInner` type represents an element of the `PollRepContent` type. +#[derive(Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)] #[allow(missing_docs)] -pub struct PollRepContent<'a> { +pub struct PollRepContentInner<'a> { pub cert_req_id: PollReqContentId, pub check_after: u64, pub reason: Option>, diff --git a/cmpv2/tests/pollrepcontent.rs b/cmpv2/tests/pollrepcontent.rs new file mode 100644 index 000000000..56c7ec6bf --- /dev/null +++ b/cmpv2/tests/pollrepcontent.rs @@ -0,0 +1,68 @@ +use cmpv2::poll::{PollRepContent, PollRepContentInner}; +use der::{Encode, asn1::Int}; +use hex_literal::hex; + +/// Verify that PollRepContent is properly encoded, i.e. according to RFC 4210 the minimal example should be encoded as follows: +/// <30 08 30 06 02 01 00 02 01 3C> +/// 0 8: SEQUENCE { +/// <30 06 02 01 00 02 01 3C> +/// 2 6: SEQUENCE { +/// <02 01 00> +/// 4 1: INTEGER 0 +/// <02 01 3C> +/// 7 1: INTEGER 60 +/// : } +/// : } +#[test] +fn test_encoding() { + let expected = hex!( + "30 08 + 30 06 + 02 01 00 + 02 01 3c" + ); + let prc = PollRepContent( + [PollRepContentInner { + cert_req_id: Int::new(&[0]).unwrap(), + check_after: 60, + reason: None, + }] + .to_vec(), + ); + + let prc_encoded = prc.to_der().unwrap(); + assert_eq!(prc_encoded, expected); +} + +/// Verify that indexing of PollRepContent is nice. ;-) +/// This basically makes sure that core::ops::Index is implemented, so we can use `prc[0]` instead of `prc.0[0]`. +#[test] +fn test_indexing() { + let prc = PollRepContent( + [PollRepContentInner { + cert_req_id: Int::new(&[0]).unwrap(), + check_after: 60, + reason: None, + }] + .to_vec(), + ); + assert_eq!(prc[0].check_after, 60); +} + +/// Verify that we can create `PollRepContent` from a `Vec`. +#[test] +fn test_from_inner() { + let inner_content_1 = PollRepContentInner { + cert_req_id: Int::new(&[1]).unwrap(), + check_after: 11, + reason: None, + }; + let inner_content_2 = PollRepContentInner { + cert_req_id: Int::new(&[2]).unwrap(), + check_after: 22, + reason: None, + }; + let prc = PollRepContent::from(vec![inner_content_1, inner_content_2]); + assert_eq!(prc[0].check_after, 11); + assert_eq!(prc[1].check_after, 22); +}