binary_data_schema/
boolean.rs1use std::{convert::TryFrom, io};
61
62use byteorder::{ReadBytesExt, WriteBytesExt};
63use serde::{
64 de::{Deserializer, Error as DeError},
65 Deserialize,
66};
67use serde_json::Value;
68
69use crate::{integer::Bitfield, Decoder, Encoder};
70
71pub const DEFAULT_LENGTH: usize = 1;
73
74#[derive(Debug, thiserror::Error)]
76pub enum ValidationError {
77 #[error(transparent)]
78 InvalidBitAddressing(#[from] crate::integer::ValidationError),
79}
80
81#[derive(Debug, thiserror::Error)]
83pub enum EncodingError {
84 #[error("The value '{value}' can not be encoded with a boolean schema")]
85 InvalidValue { value: String },
86 #[error("Failed to encode flag: {0}")]
87 Bitfield(#[from] crate::integer::EncodingError),
88}
89
90#[derive(Debug, thiserror::Error)]
92pub enum DecodingError {
93 #[error("Failed to decode flag: {0}")]
94 Bitfield(#[from] crate::integer::DecodingError),
95}
96
97impl DecodingError {
98 pub fn due_to_eof(&self) -> bool {
99 match &self {
100 Self::Bitfield(e) => e.due_to_eof(),
101 }
102 }
103}
104
105#[derive(Debug, Copy, Clone, Deserialize)]
107#[serde(rename_all = "lowercase")]
108struct RawBoolean {
109 #[serde(default = "BooleanSchema::default_length")]
110 length: usize,
111 #[serde(default, rename = "bitoffset")]
112 offset: usize,
113}
114
115#[derive(Debug, Clone)]
119pub struct BooleanSchema {
120 pub(crate) bf: Bitfield,
121}
122
123impl BooleanSchema {
124 pub fn default_length() -> usize {
125 DEFAULT_LENGTH
126 }
127 pub fn length(&self) -> usize {
128 self.bf.bytes()
129 }
130}
131
132impl From<Bitfield> for BooleanSchema {
133 fn from(bf: Bitfield) -> Self {
134 Self { bf }
135 }
136}
137
138impl TryFrom<RawBoolean> for BooleanSchema {
139 type Error = ValidationError;
140
141 fn try_from(raw: RawBoolean) -> Result<Self, Self::Error> {
142 let bf = Bitfield::new(raw.length, 1, raw.offset)?;
143
144 Ok(bf.into())
145 }
146}
147
148impl<'de> Deserialize<'de> for BooleanSchema {
149 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
150 where
151 D: Deserializer<'de>,
152 {
153 let raw = RawBoolean::deserialize(deserializer)?;
154 BooleanSchema::try_from(raw).map_err(D::Error::custom)
155 }
156}
157
158impl Encoder for BooleanSchema {
159 type Error = EncodingError;
160
161 fn encode<W>(&self, target: &mut W, value: &Value) -> Result<usize, Self::Error>
162 where
163 W: io::Write + WriteBytesExt,
164 {
165 let value = value.as_bool().ok_or_else(|| EncodingError::InvalidValue {
166 value: value.to_string(),
167 })?;
168 let int = if value { 1 } else { 0 };
169 let written = self.bf.encode(target, &int.into())?;
170
171 Ok(written)
172 }
173}
174
175impl Decoder for BooleanSchema {
176 type Error = DecodingError;
177
178 fn decode<R>(&self, target: &mut R) -> Result<Value, Self::Error>
179 where
180 R: io::Read + ReadBytesExt,
181 {
182 let int = self
183 .bf
184 .decode(target)?
185 .as_u64()
186 .expect("always u64 from BF");
187 let b = int != 0;
188 Ok(b.into())
189 }
190}
191
192#[cfg(test)]
193mod test {
194 use super::*;
195 use anyhow::Result;
196 use serde_json::{from_value, json};
197
198 #[test]
199 fn default() -> Result<()> {
200 let schema = json!({});
201 let b = from_value::<BooleanSchema>(schema)?;
202 let mut buf = [0];
203 assert_eq!(1, b.encode(&mut buf.as_mut(), &json!(true))?);
204 assert_eq!(1, buf[0]);
205
206 Ok(())
207 }
208
209 #[test]
210 fn bit3_byte2() -> Result<()> {
211 let schema = json!({
212 "bitoffset": 11,
213 "length": 2
214 });
215 let b = from_value::<BooleanSchema>(schema)?;
216 let mut buf = [0, 0];
217 assert_eq!(2, b.encode(&mut buf.as_mut(), &json!(true))?);
218 assert_eq!(1 << 3, buf[0]);
219 assert_eq!(0, buf[1]);
220 assert_eq!(2, b.encode(&mut buf.as_mut(), &json!(false))?);
221 assert_eq!(0, buf[0]);
222 assert_eq!(0, buf[1]);
223
224 Ok(())
225 }
226}