der/asn1/
boolean.rs
1use crate::{
4 asn1::Any, ByteSlice, DecodeValue, Decoder, EncodeValue, Encoder, Error, ErrorKind, FixedTag,
5 Length, OrdIsValueOrd, Result, Tag,
6};
7
8const TRUE_OCTET: u8 = 0b11111111;
13
14const FALSE_OCTET: u8 = 0b00000000;
16
17impl<'a> DecodeValue<'a> for bool {
18 fn decode_value(decoder: &mut Decoder<'a>, length: Length) -> Result<Self> {
19 if length != Length::ONE {
20 return Err(decoder.error(ErrorKind::Length { tag: Self::TAG }));
21 }
22
23 match decoder.byte()? {
24 FALSE_OCTET => Ok(false),
25 TRUE_OCTET => Ok(true),
26 _ => Err(Self::TAG.non_canonical_error()),
27 }
28 }
29}
30
31impl EncodeValue for bool {
32 fn value_len(&self) -> Result<Length> {
33 Ok(Length::ONE)
34 }
35
36 fn encode_value(&self, encoder: &mut Encoder<'_>) -> Result<()> {
37 encoder.byte(if *self { TRUE_OCTET } else { FALSE_OCTET })
38 }
39}
40
41impl FixedTag for bool {
42 const TAG: Tag = Tag::Boolean;
43}
44
45impl OrdIsValueOrd for bool {}
46
47impl From<bool> for Any<'static> {
48 fn from(value: bool) -> Any<'static> {
49 let value = ByteSlice::from(match value {
50 false => &[FALSE_OCTET],
51 true => &[TRUE_OCTET],
52 });
53
54 Any::from_tag_and_value(Tag::Boolean, value)
55 }
56}
57
58impl TryFrom<Any<'_>> for bool {
59 type Error = Error;
60
61 fn try_from(any: Any<'_>) -> Result<bool> {
62 any.try_into()
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use crate::{Decodable, Encodable};
69
70 #[test]
71 fn decode() {
72 assert_eq!(true, bool::from_der(&[0x01, 0x01, 0xFF]).unwrap());
73 assert_eq!(false, bool::from_der(&[0x01, 0x01, 0x00]).unwrap());
74 }
75
76 #[test]
77 fn encode() {
78 let mut buffer = [0u8; 3];
79 assert_eq!(
80 &[0x01, 0x01, 0xFF],
81 true.encode_to_slice(&mut buffer).unwrap()
82 );
83 assert_eq!(
84 &[0x01, 0x01, 0x00],
85 false.encode_to_slice(&mut buffer).unwrap()
86 );
87 }
88
89 #[test]
90 fn reject_non_canonical() {
91 assert!(bool::from_der(&[0x01, 0x01, 0x01]).is_err());
92 }
93}