Skip to main content

der/asn1/
bit_string.rs

1//! ASN.1 `BIT STRING` support.
2
3pub mod allowed_len_bit_string;
4
5use crate::{
6    BytesRef, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind, FixedTag, Header, Length, Reader,
7    Result, Tag, ValueOrd, Writer,
8};
9use core::{cmp::Ordering, iter::FusedIterator};
10use unused_bits::UnusedBits;
11
12#[cfg(feature = "flagset")]
13use core::mem::size_of_val;
14
15/// ASN.1 `BIT STRING` type.
16///
17/// This type contains a sequence of any number of bits, modeled internally as
18/// a sequence of bytes with a known number of "unused bits".
19///
20/// This is a zero-copy reference type which borrows from the input data.
21#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
22pub struct BitStringRef<'a> {
23    /// Number of unused bits in the final octet.
24    unused_bits: UnusedBits,
25
26    /// Bitstring represented as a slice of bytes.
27    inner: &'a BytesRef,
28}
29
30impl<'a> BitStringRef<'a> {
31    /// Create a new ASN.1 `BIT STRING` from a byte slice.
32    ///
33    /// Accepts an optional number of "unused bits" (0-7) which are omitted
34    /// from the final octet. This number is 0 if the value is octet-aligned.
35    ///
36    /// # Errors
37    /// Returns [`Error`] if any of the following occur:
38    /// - `unused_bits` is invalid
39    /// - `bytes` is too long
40    /// - an overflow occurred calculating the bit length
41    pub fn new(unused_bits: u8, bytes: &'a [u8]) -> Result<Self> {
42        let unused_bits = UnusedBits::new(unused_bits, bytes)?;
43        let inner = BytesRef::new(bytes).map_err(|_| Self::TAG.length_error())?;
44        let value = Self::new_unchecked(unused_bits, inner);
45        value
46            .bit_len_checked()
47            .ok_or_else(|| Error::from(ErrorKind::Overflow))?;
48        Ok(value)
49    }
50
51    /// Internal function. Assumptions:
52    /// - [`UnusedBits`] was checked for given [`BytesRef`],
53    /// - [`BitStringRef::bit_len_checked`] was called and returned `Ok`.
54    pub(crate) fn new_unchecked(unused_bits: UnusedBits, inner: &'a BytesRef) -> Self {
55        Self { unused_bits, inner }
56    }
57
58    /// Create a new ASN.1 `BIT STRING` from the given bytes.
59    ///
60    /// The "unused bits" are set to 0.
61    ///
62    /// # Errors
63    /// Has the same error cases as [`BitStringRef::new`].
64    pub fn from_bytes(bytes: &'a [u8]) -> Result<Self> {
65        Self::new(0, bytes)
66    }
67
68    /// Get the number of unused bits in this byte slice.
69    #[must_use]
70    pub fn unused_bits(&self) -> u8 {
71        *self.unused_bits
72    }
73
74    /// Is the number of unused bits a value other than 0?
75    #[must_use]
76    pub fn has_unused_bits(&self) -> bool {
77        *self.unused_bits != 0
78    }
79
80    /// Get the length of this `BIT STRING` in bits, or `None` if the value overflows.
81    ///
82    /// Ensured to be valid in the constructor.
83    fn bit_len_checked(&self) -> Option<usize> {
84        usize::try_from(self.inner.len())
85            .ok()
86            .and_then(|n| n.checked_mul(8))
87            .and_then(|n| n.checked_sub(usize::from(*self.unused_bits)))
88    }
89
90    /// Get the length of this `BIT STRING` in bits.
91    #[must_use]
92    pub fn bit_len(&self) -> usize {
93        let bit_len = self.bit_len_checked();
94        debug_assert!(bit_len.is_some());
95
96        // Ensured to be valid in the constructor.
97        bit_len.unwrap_or(0)
98    }
99
100    /// Get the number of bytes/octets needed to represent this `BIT STRING`
101    /// when serialized in an octet-aligned manner.
102    #[must_use]
103    pub fn byte_len(&self) -> Length {
104        self.inner.len()
105    }
106
107    /// Is the inner byte slice empty?
108    #[must_use]
109    pub fn is_empty(&self) -> bool {
110        self.inner.is_empty()
111    }
112
113    /// Borrow the inner byte slice.
114    ///
115    /// Returns `None` if the number of unused bits is *not* equal to zero,
116    /// i.e. if the `BIT STRING` is not octet aligned.
117    ///
118    /// Use [`BitString::raw_bytes`] to obtain access to the raw value
119    /// regardless of the presence of unused bits.
120    #[must_use]
121    pub fn as_bytes(&self) -> Option<&'a [u8]> {
122        if self.has_unused_bits() {
123            None
124        } else {
125            Some(self.raw_bytes())
126        }
127    }
128
129    /// Borrow the raw bytes of this `BIT STRING`.
130    ///
131    /// Note that the byte string may contain extra unused bits in the final
132    /// octet. If the number of unused bits is expected to be 0, the
133    /// [`BitStringRef::as_bytes`] function can be used instead.
134    #[must_use]
135    pub fn raw_bytes(&self) -> &'a [u8] {
136        self.inner.as_slice()
137    }
138
139    /// Iterator over the bits of this `BIT STRING`.
140    #[must_use]
141    pub fn bits(self) -> BitStringIter<'a> {
142        BitStringIter {
143            bit_string: self,
144            position: 0,
145        }
146    }
147
148    /// Returns Some(bit) if index is valid
149    #[must_use]
150    pub fn get(&self, position: usize) -> Option<bool> {
151        if position >= self.bit_len() {
152            return None;
153        }
154
155        let byte = self.raw_bytes().get(position / 8)?;
156        let bitmask = 1u8 << (7 - (position % 8));
157        Some(byte & bitmask != 0)
158    }
159}
160
161impl_any_conversions!(BitStringRef<'a>, 'a);
162
163impl<'a> DecodeValue<'a> for BitStringRef<'a> {
164    type Error = Error;
165
166    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
167        let header = header.with_length((header.length() - Length::ONE)?);
168
169        let unused_bits = reader.read_byte()?;
170        let inner = <&'a BytesRef>::decode_value(reader, header)?;
171        Self::new(unused_bits, inner.as_slice())
172    }
173}
174
175impl EncodeValue for BitStringRef<'_> {
176    fn value_len(&self) -> Result<Length> {
177        self.byte_len() + Length::ONE
178    }
179
180    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
181        writer.write_byte(*self.unused_bits)?;
182        writer.write(self.raw_bytes())
183    }
184}
185
186impl ValueOrd for BitStringRef<'_> {
187    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
188        match self.unused_bits.cmp(&other.unused_bits) {
189            Ordering::Equal => self.inner.der_cmp(other.inner),
190            ordering => Ok(ordering),
191        }
192    }
193}
194
195impl<'a> From<&BitStringRef<'a>> for BitStringRef<'a> {
196    fn from(value: &BitStringRef<'a>) -> BitStringRef<'a> {
197        *value
198    }
199}
200
201impl<'a> TryFrom<&'a [u8]> for BitStringRef<'a> {
202    type Error = Error;
203
204    fn try_from(bytes: &'a [u8]) -> Result<BitStringRef<'a>> {
205        BitStringRef::from_bytes(bytes)
206    }
207}
208
209/// Hack for simplifying the custom derive use case.
210impl<'a> TryFrom<&&'a [u8]> for BitStringRef<'a> {
211    type Error = Error;
212
213    fn try_from(bytes: &&'a [u8]) -> Result<BitStringRef<'a>> {
214        BitStringRef::from_bytes(bytes)
215    }
216}
217
218impl<'a, const N: usize> TryFrom<&'a [u8; N]> for BitStringRef<'a> {
219    type Error = Error;
220
221    fn try_from(bytes: &'a [u8; N]) -> Result<BitStringRef<'a>> {
222        BitStringRef::from_bytes(bytes)
223    }
224}
225
226impl<'a, const N: usize> TryFrom<BitStringRef<'a>> for [u8; N] {
227    type Error = Error;
228
229    fn try_from(bit_string: BitStringRef<'a>) -> Result<Self> {
230        let bytes: &[u8] = TryFrom::try_from(bit_string)?;
231        bytes
232            .try_into()
233            .map_err(|_| Tag::BitString.length_error().into())
234    }
235}
236
237impl<'a> TryFrom<BitStringRef<'a>> for &'a [u8] {
238    type Error = Error;
239
240    fn try_from(bit_string: BitStringRef<'a>) -> Result<&'a [u8]> {
241        bit_string
242            .as_bytes()
243            .ok_or_else(|| Tag::BitString.value_error().into())
244    }
245}
246
247impl FixedTag for BitStringRef<'_> {
248    const TAG: Tag = Tag::BitString;
249}
250
251/// Sealed, so that `UnusedBits` newtype can't be created directly
252mod unused_bits {
253    use core::ops::Deref;
254
255    use crate::{Result, Tag};
256
257    /// Value in range `0..=7`
258    ///
259    /// Must be zero for empty `BIT STRING`.
260    #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
261    pub(crate) struct UnusedBits(u8);
262
263    impl UnusedBits {
264        /// Maximum number of unused bits allowed.
265        pub const MAX_UNUSED_BITS: u8 = 7;
266
267        /// Represents number of "unused bits" (0-7) in `BIT STRING` which are omitted
268        /// from the final octet. This number is 0 if the value is octet-aligned.
269        pub fn new(unused_bits: u8, bytes: &[u8]) -> Result<Self> {
270            if (unused_bits > Self::MAX_UNUSED_BITS) || (unused_bits != 0 && bytes.is_empty()) {
271                Err(Tag::BitString.value_error().into())
272            } else {
273                Ok(Self(unused_bits))
274            }
275        }
276    }
277    impl Deref for UnusedBits {
278        type Target = u8;
279
280        fn deref(&self) -> &Self::Target {
281            &self.0
282        }
283    }
284}
285
286// Implement by hand because the derive would create invalid values.
287// Use the constructor to create a valid value.
288#[cfg(feature = "arbitrary")]
289impl<'a> arbitrary::Arbitrary<'a> for BitStringRef<'a> {
290    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
291        Self::new(
292            u.int_in_range(0..=UnusedBits::MAX_UNUSED_BITS)?,
293            <&'a BytesRef>::arbitrary(u)?.as_slice(),
294        )
295        .map_err(|_| arbitrary::Error::IncorrectFormat)
296    }
297
298    fn size_hint(depth: usize) -> (usize, Option<usize>) {
299        arbitrary::size_hint::and(u8::size_hint(depth), <&'a BytesRef>::size_hint(depth))
300    }
301}
302
303#[cfg(feature = "alloc")]
304pub use self::allocating::BitString;
305
306#[cfg(feature = "alloc")]
307mod allocating {
308    use super::*;
309    use crate::{asn1::Any, referenced::*};
310    use alloc::vec::Vec;
311
312    /// Owned form of ASN.1 `BIT STRING` type.
313    ///
314    /// This type provides the same functionality as [`BitStringRef`] but owns the
315    /// backing data.
316    #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
317    pub struct BitString {
318        /// Number of unused bits in the final octet.
319        unused_bits: UnusedBits,
320
321        /// Bitstring represented as a slice of bytes.
322        inner: Vec<u8>,
323    }
324
325    impl BitString {
326        /// Maximum number of unused bits allowed.
327        pub const MAX_UNUSED_BITS: u8 = 7;
328
329        /// Create a new ASN.1 `BIT STRING` from a byte slice.
330        ///
331        /// Accepts an optional number of "unused bits" (0-7) which are omitted
332        /// from the final octet. This number is 0 if the value is octet-aligned.
333        ///
334        /// # Errors
335        /// Returns [`Error`] if any of the following occur:
336        /// - `unused_bits` is invalid
337        /// - `bytes` is too long
338        /// - an overflow occurred calculating the bit length
339        pub fn new(unused_bits: u8, bytes: impl Into<Vec<u8>>) -> Result<Self> {
340            let inner = bytes.into();
341
342            // Ensure parameters parse successfully as a `BitStringRef`.
343            let ref_value = BitStringRef::new(unused_bits, &inner)?;
344
345            Ok(BitString {
346                unused_bits: ref_value.unused_bits,
347                inner,
348            })
349        }
350
351        /// Create a new ASN.1 `BIT STRING` from the given bytes.
352        ///
353        /// The "unused bits" are set to 0.
354        ///
355        /// # Errors
356        /// If `bytes` is too long.
357        pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
358            Self::new(0, bytes)
359        }
360
361        /// Get the number of unused bits in the octet serialization of this
362        /// `BIT STRING`.
363        #[must_use]
364        pub fn unused_bits(&self) -> u8 {
365            *self.unused_bits
366        }
367
368        /// Is the number of unused bits a value other than 0?
369        #[must_use]
370        pub fn has_unused_bits(&self) -> bool {
371            *self.unused_bits != 0
372        }
373
374        /// Returns inner [`BytesRef`] slice.
375        pub(crate) fn bytes_ref(&self) -> &BytesRef {
376            // Ensured to parse successfully in constructor
377            BytesRef::new_unchecked(&self.inner)
378        }
379
380        /// Get the length of this `BIT STRING` in bits, or `None` if the value overflows.
381        ///
382        /// Ensured to be valid in the constructor.
383        fn bit_len_checked(&self) -> Option<usize> {
384            BitStringRef::new_unchecked(self.unused_bits, self.bytes_ref()).bit_len_checked()
385        }
386
387        /// Get the length of this `BIT STRING` in bits.
388        #[must_use]
389        pub fn bit_len(&self) -> usize {
390            let bit_len = self.bit_len_checked();
391            debug_assert!(bit_len.is_some());
392
393            // Ensured to be valid in the constructor.
394            bit_len.unwrap_or(0)
395        }
396
397        /// Is the inner byte slice empty?
398        #[must_use]
399        pub fn is_empty(&self) -> bool {
400            self.inner.is_empty()
401        }
402
403        /// Borrow the inner byte slice.
404        ///
405        /// Returns `None` if the number of unused bits is *not* equal to zero,
406        /// i.e. if the `BIT STRING` is not octet aligned.
407        ///
408        /// Use [`BitString::raw_bytes`] to obtain access to the raw value
409        /// regardless of the presence of unused bits.
410        #[must_use]
411        pub fn as_bytes(&self) -> Option<&[u8]> {
412            if self.has_unused_bits() {
413                None
414            } else {
415                Some(self.raw_bytes())
416            }
417        }
418
419        /// Borrow the raw bytes of this `BIT STRING`.
420        #[must_use]
421        pub fn raw_bytes(&self) -> &[u8] {
422            self.inner.as_slice()
423        }
424
425        /// Iterator over the bits of this `BIT STRING`.
426        #[must_use]
427        pub fn bits(&self) -> BitStringIter<'_> {
428            BitStringRef::from(self).bits()
429        }
430
431        /// Returns Some(bit) if index is valid
432        #[must_use]
433        pub fn get(&self, position: usize) -> Option<bool> {
434            BitStringRef::from(self).get(position)
435        }
436    }
437
438    impl_any_conversions!(BitString);
439
440    impl<'a> DecodeValue<'a> for BitString {
441        type Error = Error;
442
443        fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
444            let inner_len = (header.length() - Length::ONE)?;
445            let unused_bits = reader.read_byte()?;
446            let inner = reader.read_vec(inner_len)?;
447            Self::new(unused_bits, inner)
448        }
449    }
450
451    impl EncodeValue for BitString {
452        fn value_len(&self) -> Result<Length> {
453            Length::ONE + Length::try_from(self.inner.len())?
454        }
455
456        fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
457            writer.write_byte(*self.unused_bits)?;
458            writer.write(&self.inner)
459        }
460    }
461
462    impl FixedTag for BitString {
463        const TAG: Tag = Tag::BitString;
464    }
465
466    impl<'a> From<&'a BitString> for BitStringRef<'a> {
467        fn from(bit_string: &'a BitString) -> BitStringRef<'a> {
468            // Ensured to parse successfully in constructor
469            BitStringRef::new_unchecked(bit_string.unused_bits, bit_string.bytes_ref())
470        }
471    }
472
473    impl From<BitStringRef<'_>> for Any {
474        fn from(bit_string_ref: BitStringRef<'_>) -> Any {
475            Any::from(&bit_string_ref)
476        }
477    }
478
479    impl From<&BitStringRef<'_>> for Any {
480        fn from(bit_string_ref: &BitStringRef<'_>) -> Any {
481            Any::encode_from(bit_string_ref).expect("should encode successfully")
482        }
483    }
484
485    impl From<BitString> for Any {
486        fn from(bit_string: BitString) -> Any {
487            bit_string.owned_to_ref().into()
488        }
489    }
490
491    impl From<&BitString> for Any {
492        fn from(bit_string: &BitString) -> Any {
493            bit_string.owned_to_ref().into()
494        }
495    }
496
497    /// Hack for simplifying the custom derive use case.
498    impl<'a> TryFrom<&'a Vec<u8>> for BitStringRef<'a> {
499        type Error = Error;
500
501        fn try_from(bytes: &'a Vec<u8>) -> Result<BitStringRef<'a>> {
502            BitStringRef::from_bytes(bytes)
503        }
504    }
505
506    /// Hack for simplifying the custom derive use case.
507    impl<'a> TryFrom<BitStringRef<'a>> for Vec<u8> {
508        type Error = Error;
509
510        fn try_from(bit_string: BitStringRef<'a>) -> Result<Vec<u8>> {
511            bit_string
512                .as_bytes()
513                .map(<[u8]>::to_vec)
514                .ok_or_else(|| Tag::BitString.value_error().into())
515        }
516    }
517
518    impl ValueOrd for BitString {
519        fn value_cmp(&self, other: &Self) -> Result<Ordering> {
520            match self.unused_bits.cmp(&other.unused_bits) {
521                Ordering::Equal => self.inner.der_cmp(&other.inner),
522                ordering => Ok(ordering),
523            }
524        }
525    }
526
527    // Implement by hand because the derive would create invalid values.
528    // Use the constructor to create a valid value.
529    #[cfg(feature = "arbitrary")]
530    impl<'a> arbitrary::Arbitrary<'a> for BitString {
531        fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
532            Self::new(
533                u.int_in_range(0..=Self::MAX_UNUSED_BITS)?,
534                <&'a BytesRef>::arbitrary(u)?.as_slice(),
535            )
536            .map_err(|_| arbitrary::Error::IncorrectFormat)
537        }
538
539        fn size_hint(depth: usize) -> (usize, Option<usize>) {
540            arbitrary::size_hint::and(u8::size_hint(depth), <&'a BytesRef>::size_hint(depth))
541        }
542    }
543
544    impl<'a> RefToOwned<'a> for BitStringRef<'a> {
545        type Owned = BitString;
546        fn ref_to_owned(&self) -> Self::Owned {
547            BitString {
548                unused_bits: self.unused_bits,
549                inner: Vec::from(self.inner.as_slice()),
550            }
551        }
552    }
553
554    impl OwnedToRef for BitString {
555        type Borrowed<'a> = BitStringRef<'a>;
556        fn owned_to_ref(&self) -> Self::Borrowed<'_> {
557            self.into()
558        }
559    }
560}
561
562/// Iterator over the bits of a [`BitString`].
563#[derive(Debug)]
564pub struct BitStringIter<'a> {
565    /// [`BitString`] being iterated over.
566    bit_string: BitStringRef<'a>,
567
568    /// Current bit position within the iterator.
569    position: usize,
570}
571
572impl Iterator for BitStringIter<'_> {
573    type Item = bool;
574
575    #[allow(clippy::arithmetic_side_effects)]
576    fn next(&mut self) -> Option<bool> {
577        if self.position >= self.bit_string.bit_len() {
578            return None;
579        }
580
581        let byte = self.bit_string.raw_bytes().get(self.position / 8)?;
582        let bit = 1u8 << (7 - (self.position % 8));
583        self.position = self.position.checked_add(1)?;
584        Some(byte & bit != 0)
585    }
586
587    fn size_hint(&self) -> (usize, Option<usize>) {
588        let len = self.bit_string.bit_len().saturating_sub(self.position);
589        (len, Some(len))
590    }
591}
592
593impl ExactSizeIterator for BitStringIter<'_> {
594    fn len(&self) -> usize {
595        self.bit_string.bit_len()
596    }
597}
598
599impl FusedIterator for BitStringIter<'_> {}
600
601#[cfg(feature = "flagset")]
602impl<T: flagset::Flags> FixedTag for flagset::FlagSet<T> {
603    const TAG: Tag = BitStringRef::TAG;
604}
605
606#[cfg(feature = "flagset")]
607impl<T> ValueOrd for flagset::FlagSet<T>
608where
609    T: flagset::Flags,
610    T::Type: Ord,
611{
612    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
613        Ok(self.bits().cmp(&other.bits()))
614    }
615}
616
617#[cfg(feature = "flagset")]
618#[allow(clippy::arithmetic_side_effects)]
619impl<'a, T> DecodeValue<'a> for flagset::FlagSet<T>
620where
621    T: flagset::Flags,
622    T::Type: From<bool>,
623    T::Type: core::ops::Shl<usize, Output = T::Type>,
624{
625    type Error = Error;
626
627    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
628        let position = reader.position();
629        let bits = BitStringRef::decode_value(reader, header)?;
630
631        let mut flags = T::none().bits();
632
633        if bits.bit_len() > size_of_val(&flags) * 8 {
634            return Err(Error::new(ErrorKind::Overlength, position));
635        }
636
637        for (i, bit) in bits.bits().enumerate() {
638            flags |= T::Type::from(bit) << i;
639        }
640
641        Ok(Self::new_truncated(flags))
642    }
643}
644
645#[cfg(feature = "flagset")]
646#[allow(clippy::arithmetic_side_effects)]
647#[inline(always)]
648fn encode_flagset<T>(set: &flagset::FlagSet<T>) -> (usize, [u8; 16])
649where
650    T: flagset::Flags,
651    u128: From<T::Type>,
652{
653    let bits: u128 = set.bits().into();
654    let mut swap = 0u128;
655
656    for i in 0..128 {
657        let on = bits & (1 << i);
658        swap |= on >> i << (128 - i - 1);
659    }
660
661    (bits.leading_zeros() as usize, swap.to_be_bytes())
662}
663
664#[cfg(feature = "flagset")]
665#[allow(clippy::cast_possible_truncation, clippy::arithmetic_side_effects)]
666impl<T: flagset::Flags> EncodeValue for flagset::FlagSet<T>
667where
668    T::Type: From<bool>,
669    T::Type: core::ops::Shl<usize, Output = T::Type>,
670    u128: From<T::Type>,
671{
672    fn value_len(&self) -> Result<Length> {
673        let (lead, buff) = encode_flagset(self);
674        let buff = &buff[..buff.len() - lead / 8];
675        BitStringRef::new((lead % 8) as u8, buff)?.value_len()
676    }
677
678    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
679        let (lead, buff) = encode_flagset(self);
680        let buff = &buff[..buff.len() - lead / 8];
681        BitStringRef::new((lead % 8) as u8, buff)?.encode_value(writer)
682    }
683}
684
685#[cfg(test)]
686#[allow(clippy::unwrap_used)]
687mod tests {
688    use core::cmp::Ordering;
689
690    use super::{BitStringRef, Result, Tag};
691    use crate::asn1::AnyRef;
692    use hex_literal::hex;
693
694    /// Parse a `BitString` from an ASN.1 `Any` value to test decoding behaviors.
695    fn parse_bitstring(bytes: &[u8]) -> Result<BitStringRef<'_>> {
696        AnyRef::new(Tag::BitString, bytes)?.try_into()
697    }
698
699    #[test]
700    fn decode_empty_bitstring() {
701        let bs = parse_bitstring(&hex!("00")).unwrap();
702        assert_eq!(bs.as_bytes().unwrap(), &[]);
703    }
704
705    #[test]
706    fn decode_non_empty_bitstring() {
707        let bs = parse_bitstring(&hex!("00010203")).unwrap();
708        assert_eq!(bs.as_bytes().unwrap(), &[0x01, 0x02, 0x03]);
709    }
710
711    #[test]
712    fn decode_bitstring_with_unused_bits() {
713        let bs = parse_bitstring(&hex!("066e5dc0")).unwrap();
714        assert_eq!(bs.unused_bits(), 6);
715        assert_eq!(bs.raw_bytes(), &hex!("6e5dc0"));
716
717        // Expected: 011011100101110111
718        let mut bits = bs.bits();
719        assert_eq!(bits.len(), 18);
720
721        for bit in [0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1] {
722            assert_eq!(u8::from(bits.next().unwrap()), bit);
723        }
724
725        // Ensure `None` is returned on successive calls
726        assert_eq!(bits.next(), None);
727        assert_eq!(bits.next(), None);
728    }
729
730    #[test]
731    fn reject_unused_bits_in_empty_string() {
732        assert_eq!(
733            parse_bitstring(&[0x03]).err().unwrap().kind(),
734            Tag::BitString.value_error()
735        );
736    }
737
738    #[test]
739    fn bitstring_valueord_value_cmp() {
740        use crate::ord::DerOrd;
741
742        let bs1 = parse_bitstring(&hex!("00010204")).unwrap();
743        let bs2 = parse_bitstring(&hex!("00010203")).unwrap();
744        assert_eq!(bs1.der_cmp(&bs2), Ok(Ordering::Greater));
745    }
746}