ndarray_npy/npy/elements/
bool.rs1use super::{bytes_as_mut_slice, bytes_as_slice, check_for_extra_bytes};
4use crate::{ReadDataError, ReadableElement, ViewDataError, ViewElement, ViewMutElement};
5use py_literal::Value as PyValue;
6use std::error::Error;
7use std::fmt;
8use std::io;
9use std::mem;
10
11#[derive(Debug)]
13struct ParseBoolError {
14 bad_value: u8,
15}
16
17impl Error for ParseBoolError {
18 fn source(&self) -> Option<&(dyn Error + 'static)> {
19 None
20 }
21}
22
23impl fmt::Display for ParseBoolError {
24 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25 write!(f, "error parsing value {:#04x} as a bool", self.bad_value)
26 }
27}
28
29impl From<ParseBoolError> for ReadDataError {
30 fn from(err: ParseBoolError) -> ReadDataError {
31 ReadDataError::ParseData(Box::new(err))
32 }
33}
34
35impl From<ParseBoolError> for ViewDataError {
36 fn from(err: ParseBoolError) -> ViewDataError {
37 ViewDataError::InvalidData(Box::new(err))
38 }
39}
40
41fn check_valid_for_bool(bytes: &[u8]) -> Result<(), ParseBoolError> {
49 for &byte in bytes {
50 if byte > 1 {
51 return Err(ParseBoolError { bad_value: byte });
52 }
53 }
54 Ok(())
55}
56
57impl ReadableElement for bool {
58 fn read_to_end_exact_vec<R: io::Read>(
59 mut reader: R,
60 type_desc: &PyValue,
61 len: usize,
62 ) -> Result<Vec<Self>, ReadDataError> {
63 match *type_desc {
64 PyValue::String(ref s) if s == "|b1" => {
65 let mut bytes: Vec<u8> = vec![0; len];
67 reader.read_exact(&mut bytes)?;
68 check_for_extra_bytes(&mut reader)?;
69
70 check_valid_for_bool(&bytes)?;
72
73 {
75 let ptr: *mut u8 = bytes.as_mut_ptr();
76 let len: usize = bytes.len();
77 let cap: usize = bytes.capacity();
78 mem::forget(bytes);
79 Ok(unsafe { Vec::from_raw_parts(ptr.cast::<bool>(), len, cap) })
92 }
93 }
94 ref other => Err(ReadDataError::WrongDescriptor(other.clone())),
95 }
96 }
97}
98
99impl_writable_element_always_valid_cast!(bool, "|b1", "|b1");
103
104impl ViewElement for bool {
105 fn bytes_as_slice<'a>(
106 bytes: &'a [u8],
107 type_desc: &PyValue,
108 len: usize,
109 ) -> Result<&'a [Self], ViewDataError> {
110 match *type_desc {
111 PyValue::String(ref s) if s == "|b1" => {
112 check_valid_for_bool(bytes)?;
113 unsafe { bytes_as_slice(bytes, len) }
114 }
115 ref other => Err(ViewDataError::WrongDescriptor(other.clone())),
116 }
117 }
118}
119
120impl ViewMutElement for bool {
121 fn bytes_as_mut_slice<'a>(
122 bytes: &'a mut [u8],
123 type_desc: &PyValue,
124 len: usize,
125 ) -> Result<&'a mut [Self], ViewDataError> {
126 match *type_desc {
127 PyValue::String(ref s) if s == "|b1" => {
128 check_valid_for_bool(bytes)?;
129 unsafe { bytes_as_mut_slice(bytes, len) }
130 }
131 ref other => Err(ViewDataError::WrongDescriptor(other.clone())),
132 }
133 }
134}