rasn/types/strings/
octet.rs

1use crate::prelude::*;
2
3use alloc::vec::Vec;
4
5pub use bytes::Bytes as OctetString;
6
7#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
8pub struct FixedOctetString<const N: usize>([u8; N]);
9
10impl<const N: usize> FixedOctetString<N> {
11    pub fn new(value: [u8; N]) -> Self {
12        Self(value)
13    }
14}
15
16impl<const N: usize> From<[u8; N]> for FixedOctetString<N> {
17    fn from(value: [u8; N]) -> Self {
18        Self::new(value)
19    }
20}
21
22impl<const N: usize> TryFrom<Vec<u8>> for FixedOctetString<N> {
23    type Error = <[u8; N] as TryFrom<Vec<u8>>>::Error;
24
25    fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
26        value.try_into().map(Self)
27    }
28}
29
30impl<const N: usize> TryFrom<&[u8]> for FixedOctetString<N> {
31    type Error = <[u8; N] as TryFrom<&'static [u8]>>::Error;
32
33    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
34        value.try_into().map(Self)
35    }
36}
37
38impl<const N: usize> TryFrom<OctetString> for FixedOctetString<N> {
39    type Error = <[u8; N] as TryFrom<&'static [u8]>>::Error;
40
41    fn try_from(value: OctetString) -> Result<Self, Self::Error> {
42        (&*value).try_into().map(Self)
43    }
44}
45
46impl<const N: usize> core::ops::Deref for FixedOctetString<N> {
47    type Target = [u8; N];
48
49    fn deref(&self) -> &Self::Target {
50        &self.0
51    }
52}
53
54impl<const N: usize> core::ops::DerefMut for FixedOctetString<N> {
55    fn deref_mut(&mut self) -> &mut Self::Target {
56        &mut self.0
57    }
58}
59
60impl<const N: usize> AsnType for FixedOctetString<N> {
61    const TAG: Tag = Tag::OCTET_STRING;
62    const CONSTRAINTS: Constraints<'static> = Constraints::new(&[Constraint::Size(
63        Extensible::new(constraints::Size::fixed(N)),
64    )]);
65}
66
67impl<const N: usize> Decode for FixedOctetString<N> {
68    fn decode_with_tag_and_constraints<D: Decoder>(
69        decoder: &mut D,
70        tag: Tag,
71        constraints: Constraints,
72    ) -> Result<Self, D::Error> {
73        decoder
74            .decode_octet_string(tag, constraints)?
75            .try_into()
76            .map(Self)
77            .map_err(|vec| {
78                D::Error::from(crate::error::DecodeError::fixed_string_conversion_failed(
79                    Tag::OCTET_STRING,
80                    vec.len(),
81                    N,
82                    decoder.codec(),
83                ))
84            })
85    }
86}
87
88impl<const N: usize> Encode for FixedOctetString<N> {
89    fn encode_with_tag_and_constraints<E: Encoder>(
90        &self,
91        encoder: &mut E,
92        tag: Tag,
93        constraints: Constraints,
94    ) -> Result<(), E::Error> {
95        encoder
96            .encode_octet_string(tag, constraints, &self.0)
97            .map(drop)
98    }
99}