1use crate::{
4 DecodeValue, EncodeValue, Error, ErrorKind, FixedTag, Header, Length, Reader, Result, Tag,
5 Writer, asn1::AnyRef, ord::OrdIsValueOrd,
6};
7
8const TRUE_OCTET: u8 = 0b11111111;
13
14const FALSE_OCTET: u8 = 0b00000000;
16
17impl<'a> DecodeValue<'a> for bool {
18 type Error = Error;
19
20 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
21 if header.length() != Length::ONE {
22 return Err(reader.error(ErrorKind::Length { tag: Self::TAG }));
23 }
24
25 match reader.read_byte()? {
26 FALSE_OCTET => Ok(false),
27 TRUE_OCTET => Ok(true),
28 _ => Err(reader.error(Self::TAG.non_canonical_error())),
29 }
30 }
31}
32
33impl EncodeValue for bool {
34 fn value_len(&self) -> Result<Length> {
35 Ok(Length::ONE)
36 }
37
38 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
39 writer.write_byte(if *self { TRUE_OCTET } else { FALSE_OCTET })
40 }
41}
42
43impl FixedTag for bool {
44 const TAG: Tag = Tag::Boolean;
45}
46
47impl OrdIsValueOrd for bool {}
48
49impl TryFrom<AnyRef<'_>> for bool {
50 type Error = Error;
51
52 fn try_from(any: AnyRef<'_>) -> Result<bool> {
53 any.decode_as()
54 }
55}
56
57#[cfg(test)]
58#[allow(clippy::unwrap_used, clippy::bool_assert_comparison)]
59mod tests {
60 use crate::{Decode, Encode, asn1::AnyRef};
61
62 #[test]
63 fn try_from_any() {
64 let true_value = AnyRef::from_der(&[0x01, 0x01, 0xFF]).unwrap();
65 let false_value = AnyRef::from_der(&[0x01, 0x01, 0x00]).unwrap();
66 assert_eq!(bool::try_from(true_value).unwrap(), true);
67 assert_eq!(bool::try_from(false_value).unwrap(), false);
68 }
69
70 #[test]
71 fn try_from_any_rejects_invalid_input() {
72 for bytes in [
73 &[0x02, 0x01, 0x00][..], &[0x01, 0x00], &[0x01, 0x02, 0x00, 0x00], &[0x01, 0x01, 0x01], ] {
78 let any = AnyRef::from_der(bytes).unwrap();
79 assert!(bool::try_from(any).is_err());
80 }
81 }
82
83 #[test]
84 fn decode() {
85 assert_eq!(true, bool::from_der(&[0x01, 0x01, 0xFF]).unwrap());
86 assert_eq!(false, bool::from_der(&[0x01, 0x01, 0x00]).unwrap());
87 }
88
89 #[test]
90 fn encode() {
91 let mut buffer = [0u8; 3];
92 assert_eq!(
93 &[0x01, 0x01, 0xFF],
94 true.encode_to_slice(&mut buffer).unwrap()
95 );
96 assert_eq!(
97 &[0x01, 0x01, 0x00],
98 false.encode_to_slice(&mut buffer).unwrap()
99 );
100 }
101
102 #[test]
103 fn reject_non_canonical() {
104 assert!(bool::from_der(&[0x01, 0x01, 0x01]).is_err());
105 }
106}