1use crate::{
4 asn1::AnyRef, ord::OrdIsValueOrd, ByteSlice, DecodeValue, EncodeValue, Error, ErrorKind,
5 FixedTag, Header, Length, Reader, Result, Tag, Writer,
6};
7
8#[cfg(feature = "alloc")]
9use alloc::vec::Vec;
10
11#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
17pub struct OctetStringRef<'a> {
18 inner: ByteSlice<'a>,
20}
21
22impl<'a> OctetStringRef<'a> {
23 pub fn new(slice: &'a [u8]) -> Result<Self> {
25 ByteSlice::new(slice)
26 .map(|inner| Self { inner })
27 .map_err(|_| ErrorKind::Length { tag: Self::TAG }.into())
28 }
29
30 pub fn as_bytes(&self) -> &'a [u8] {
32 self.inner.as_slice()
33 }
34
35 pub fn len(&self) -> Length {
37 self.inner.len()
38 }
39
40 pub fn is_empty(&self) -> bool {
42 self.inner.is_empty()
43 }
44}
45
46impl AsRef<[u8]> for OctetStringRef<'_> {
47 fn as_ref(&self) -> &[u8] {
48 self.as_bytes()
49 }
50}
51
52impl<'a> DecodeValue<'a> for OctetStringRef<'a> {
53 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
54 let inner = ByteSlice::decode_value(reader, header)?;
55 Ok(Self { inner })
56 }
57}
58
59impl EncodeValue for OctetStringRef<'_> {
60 fn value_len(&self) -> Result<Length> {
61 self.inner.value_len()
62 }
63
64 fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
65 self.inner.encode_value(writer)
66 }
67}
68
69impl FixedTag for OctetStringRef<'_> {
70 const TAG: Tag = Tag::OctetString;
71}
72
73impl OrdIsValueOrd for OctetStringRef<'_> {}
74
75impl<'a> From<&OctetStringRef<'a>> for OctetStringRef<'a> {
76 fn from(value: &OctetStringRef<'a>) -> OctetStringRef<'a> {
77 *value
78 }
79}
80
81impl<'a> TryFrom<AnyRef<'a>> for OctetStringRef<'a> {
82 type Error = Error;
83
84 fn try_from(any: AnyRef<'a>) -> Result<OctetStringRef<'a>> {
85 any.decode_into()
86 }
87}
88
89impl<'a> From<OctetStringRef<'a>> for AnyRef<'a> {
90 fn from(octet_string: OctetStringRef<'a>) -> AnyRef<'a> {
91 AnyRef::from_tag_and_value(Tag::OctetString, octet_string.inner)
92 }
93}
94
95impl<'a> From<OctetStringRef<'a>> for &'a [u8] {
96 fn from(octet_string: OctetStringRef<'a>) -> &'a [u8] {
97 octet_string.as_bytes()
98 }
99}
100
101#[cfg(feature = "alloc")]
108#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
109#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
110pub struct OctetString {
111 inner: Vec<u8>,
113}
114
115#[cfg(feature = "alloc")]
116impl OctetString {
117 pub fn new(bytes: impl Into<Vec<u8>>) -> Result<Self> {
119 let inner = bytes.into();
120
121 OctetStringRef::new(&inner)?;
123
124 Ok(Self { inner })
125 }
126
127 pub fn as_bytes(&self) -> &[u8] {
129 self.inner.as_slice()
130 }
131
132 pub fn len(&self) -> Length {
134 self.value_len().expect("invalid OCTET STRING length")
135 }
136
137 pub fn is_empty(&self) -> bool {
139 self.inner.is_empty()
140 }
141}
142
143#[cfg(feature = "alloc")]
144impl AsRef<[u8]> for OctetString {
145 fn as_ref(&self) -> &[u8] {
146 self.as_bytes()
147 }
148}
149
150#[cfg(feature = "alloc")]
151impl<'a> DecodeValue<'a> for OctetString {
152 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
153 Self::new(reader.read_vec(header.length)?)
154 }
155}
156
157#[cfg(feature = "alloc")]
158impl EncodeValue for OctetString {
159 fn value_len(&self) -> Result<Length> {
160 self.inner.len().try_into()
161 }
162
163 fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
164 writer.write(&self.inner)
165 }
166}
167
168#[cfg(feature = "alloc")]
169impl FixedTag for OctetString {
170 const TAG: Tag = Tag::OctetString;
171}
172
173#[cfg(feature = "alloc")]
174impl<'a> From<&'a OctetString> for OctetStringRef<'a> {
175 fn from(octet_string: &'a OctetString) -> OctetStringRef<'a> {
176 OctetStringRef::new(&octet_string.inner).expect("invalid OCTET STRING")
178 }
179}
180
181#[cfg(feature = "alloc")]
182impl OrdIsValueOrd for OctetString {}