1 //! Trait implementations on `BitArray`. 2 3 use crate::{ 4 array::BitArray, 5 index::BitIdx, 6 order::BitOrder, 7 slice::BitSlice, 8 store::BitStore, 9 view::BitView, 10 }; 11 12 use core::{ 13 borrow::{ 14 Borrow, 15 BorrowMut, 16 }, 17 cmp, 18 convert::TryFrom, 19 fmt::{ 20 self, 21 Binary, 22 Debug, 23 Display, 24 Formatter, 25 LowerHex, 26 Octal, 27 UpperHex, 28 }, 29 hash::{ 30 Hash, 31 Hasher, 32 }, 33 }; 34 35 #[cfg(not(tarpaulin_include))] 36 impl<O, V> Borrow<BitSlice<O, V::Store>> for BitArray<O, V> 37 where 38 O: BitOrder, 39 V: BitView + Sized, 40 { 41 #[inline(always)] borrow(&self) -> &BitSlice<O, V::Store>42 fn borrow(&self) -> &BitSlice<O, V::Store> { 43 self.as_bitslice() 44 } 45 } 46 47 #[cfg(not(tarpaulin_include))] 48 impl<O, V> BorrowMut<BitSlice<O, V::Store>> for BitArray<O, V> 49 where 50 O: BitOrder, 51 V: BitView + Sized, 52 { 53 #[inline(always)] borrow_mut(&mut self) -> &mut BitSlice<O, V::Store>54 fn borrow_mut(&mut self) -> &mut BitSlice<O, V::Store> { 55 self.as_mut_bitslice() 56 } 57 } 58 59 impl<O, V> Eq for BitArray<O, V> 60 where 61 O: BitOrder, 62 V: BitView + Sized, 63 { 64 } 65 66 #[cfg(not(tarpaulin_include))] 67 impl<O, V> Ord for BitArray<O, V> 68 where 69 O: BitOrder, 70 V: BitView + Sized, 71 { 72 #[inline] cmp(&self, other: &Self) -> cmp::Ordering73 fn cmp(&self, other: &Self) -> cmp::Ordering { 74 self.as_bitslice().cmp(other.as_bitslice()) 75 } 76 } 77 78 #[cfg(not(tarpaulin_include))] 79 impl<O, V, T> PartialEq<BitArray<O, V>> for BitSlice<O, T> 80 where 81 O: BitOrder, 82 V: BitView + Sized, 83 T: BitStore, 84 { 85 #[inline] eq(&self, other: &BitArray<O, V>) -> bool86 fn eq(&self, other: &BitArray<O, V>) -> bool { 87 self == other.as_bitslice() 88 } 89 } 90 91 #[cfg(not(tarpaulin_include))] 92 impl<O, V, Rhs> PartialEq<Rhs> for BitArray<O, V> 93 where 94 O: BitOrder, 95 V: BitView + Sized, 96 Rhs: ?Sized, 97 BitSlice<O, V::Store>: PartialEq<Rhs>, 98 { 99 #[inline] eq(&self, other: &Rhs) -> bool100 fn eq(&self, other: &Rhs) -> bool { 101 self.as_bitslice() == other 102 } 103 } 104 105 #[cfg(not(tarpaulin_include))] 106 impl<O, V, T> PartialOrd<BitArray<O, V>> for BitSlice<O, T> 107 where 108 O: BitOrder, 109 V: BitView + Sized, 110 T: BitStore, 111 { 112 #[inline] partial_cmp(&self, other: &BitArray<O, V>) -> Option<cmp::Ordering>113 fn partial_cmp(&self, other: &BitArray<O, V>) -> Option<cmp::Ordering> { 114 self.partial_cmp(other.as_bitslice()) 115 } 116 } 117 118 #[cfg(not(tarpaulin_include))] 119 impl<O, V, Rhs> PartialOrd<Rhs> for BitArray<O, V> 120 where 121 O: BitOrder, 122 V: BitView + Sized, 123 Rhs: ?Sized, 124 BitSlice<O, V::Store>: PartialOrd<Rhs>, 125 { 126 #[inline] partial_cmp(&self, other: &Rhs) -> Option<cmp::Ordering>127 fn partial_cmp(&self, other: &Rhs) -> Option<cmp::Ordering> { 128 self.as_bitslice().partial_cmp(other) 129 } 130 } 131 132 #[cfg(not(tarpaulin_include))] 133 impl<O, V> AsRef<BitSlice<O, V::Store>> for BitArray<O, V> 134 where 135 O: BitOrder, 136 V: BitView + Sized, 137 { 138 #[inline(always)] as_ref(&self) -> &BitSlice<O, V::Store>139 fn as_ref(&self) -> &BitSlice<O, V::Store> { 140 self.as_bitslice() 141 } 142 } 143 144 #[cfg(not(tarpaulin_include))] 145 impl<O, V> AsMut<BitSlice<O, V::Store>> for BitArray<O, V> 146 where 147 O: BitOrder, 148 V: BitView + Sized, 149 { 150 #[inline(always)] as_mut(&mut self) -> &mut BitSlice<O, V::Store>151 fn as_mut(&mut self) -> &mut BitSlice<O, V::Store> { 152 self.as_mut_bitslice() 153 } 154 } 155 156 #[cfg(not(tarpaulin_include))] 157 impl<O, V> From<V> for BitArray<O, V> 158 where 159 O: BitOrder, 160 V: BitView + Sized, 161 { 162 #[inline(always)] from(data: V) -> Self163 fn from(data: V) -> Self { 164 Self::new(data) 165 } 166 } 167 168 impl<O1, O2, T, V> TryFrom<&'_ BitSlice<O2, T>> for BitArray<O1, V> 169 where 170 O1: BitOrder, 171 O2: BitOrder, 172 T: BitStore, 173 V: BitView + Sized, 174 { 175 type Error = TryFromBitSliceError; 176 177 #[inline] try_from(src: &BitSlice<O2, T>) -> Result<Self, Self::Error>178 fn try_from(src: &BitSlice<O2, T>) -> Result<Self, Self::Error> { 179 if src.len() != V::const_bits() { 180 return Self::Error::err(); 181 } 182 let mut out = Self::zeroed(); 183 out.clone_from_bitslice(src); 184 Ok(out) 185 } 186 } 187 188 impl<'a, O, V> TryFrom<&'a BitSlice<O, V::Store>> for &'a BitArray<O, V> 189 where 190 O: BitOrder, 191 V: BitView + Sized, 192 { 193 type Error = TryFromBitSliceError; 194 195 #[inline] try_from(src: &'a BitSlice<O, V::Store>) -> Result<Self, Self::Error>196 fn try_from(src: &'a BitSlice<O, V::Store>) -> Result<Self, Self::Error> { 197 let bitptr = src.bitptr(); 198 // This pointer cast can only happen if the slice is exactly as long as 199 // the array, and is aligned to the front of the element. 200 if src.len() != V::const_bits() || bitptr.head() != BitIdx::ZERO { 201 return Self::Error::err(); 202 } 203 Ok(unsafe { &*(bitptr.pointer().to_const() as *const BitArray<O, V>) }) 204 } 205 } 206 207 impl<'a, O, V> TryFrom<&'a mut BitSlice<O, V::Store>> for &'a mut BitArray<O, V> 208 where 209 O: BitOrder, 210 V: BitView + Sized, 211 { 212 type Error = TryFromBitSliceError; 213 214 #[inline] try_from( src: &'a mut BitSlice<O, V::Store>, ) -> Result<Self, Self::Error>215 fn try_from( 216 src: &'a mut BitSlice<O, V::Store>, 217 ) -> Result<Self, Self::Error> { 218 let bitptr = src.bitptr(); 219 if src.len() != V::const_bits() || bitptr.head() != BitIdx::ZERO { 220 return Self::Error::err(); 221 } 222 Ok(unsafe { &mut *(bitptr.pointer().to_mut() as *mut BitArray<O, V>) }) 223 } 224 } 225 226 #[cfg(not(tarpaulin_include))] 227 impl<O, V> Default for BitArray<O, V> 228 where 229 O: BitOrder, 230 V: BitView + Sized, 231 { 232 #[inline(always)] default() -> Self233 fn default() -> Self { 234 Self::zeroed() 235 } 236 } 237 238 #[cfg(not(tarpaulin_include))] 239 impl<O, V> Binary for BitArray<O, V> 240 where 241 O: BitOrder, 242 V: BitView + Sized, 243 { 244 #[inline] fmt(&self, fmt: &mut Formatter) -> fmt::Result245 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { 246 Binary::fmt(self.as_bitslice(), fmt) 247 } 248 } 249 250 impl<O, V> Debug for BitArray<O, V> 251 where 252 O: BitOrder, 253 V: BitView + Sized, 254 { 255 #[inline] fmt(&self, fmt: &mut Formatter) -> fmt::Result256 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { 257 if fmt.alternate() { 258 self.bitptr().render( 259 fmt, 260 "Array", 261 Some(core::any::type_name::<O>()), 262 None, 263 )?; 264 fmt.write_str(" ")?; 265 } 266 Binary::fmt(self, fmt) 267 } 268 } 269 270 #[cfg(not(tarpaulin_include))] 271 impl<O, V> Display for BitArray<O, V> 272 where 273 O: BitOrder, 274 V: BitView + Sized, 275 { 276 #[inline] fmt(&self, fmt: &mut Formatter) -> fmt::Result277 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { 278 Binary::fmt(self.as_bitslice(), fmt) 279 } 280 } 281 282 #[cfg(not(tarpaulin_include))] 283 impl<O, V> LowerHex for BitArray<O, V> 284 where 285 O: BitOrder, 286 V: BitView + Sized, 287 { 288 #[inline] fmt(&self, fmt: &mut Formatter) -> fmt::Result289 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { 290 LowerHex::fmt(self.as_bitslice(), fmt) 291 } 292 } 293 294 #[cfg(not(tarpaulin_include))] 295 impl<O, V> Octal for BitArray<O, V> 296 where 297 O: BitOrder, 298 V: BitView + Sized, 299 { 300 #[inline] fmt(&self, fmt: &mut Formatter) -> fmt::Result301 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { 302 Octal::fmt(self.as_bitslice(), fmt) 303 } 304 } 305 306 #[cfg(not(tarpaulin_include))] 307 impl<O, V> UpperHex for BitArray<O, V> 308 where 309 O: BitOrder, 310 V: BitView + Sized, 311 { 312 #[inline] fmt(&self, fmt: &mut Formatter) -> fmt::Result313 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { 314 UpperHex::fmt(self.as_bitslice(), fmt) 315 } 316 } 317 318 #[cfg(not(tarpaulin_include))] 319 impl<O, V> Hash for BitArray<O, V> 320 where 321 O: BitOrder, 322 V: BitView + Sized, 323 { 324 #[inline] hash<H>(&self, hasher: &mut H) where H: Hasher325 fn hash<H>(&self, hasher: &mut H) 326 where H: Hasher { 327 self.as_bitslice().hash(hasher) 328 } 329 } 330 331 #[cfg(not(tarpaulin_include))] 332 impl<'a, O, V> IntoIterator for &'a BitArray<O, V> 333 where 334 O: 'a + BitOrder, 335 V: 'a + BitView + Sized, 336 { 337 type IntoIter = <&'a BitSlice<O, V::Store> as IntoIterator>::IntoIter; 338 type Item = <&'a BitSlice<O, V::Store> as IntoIterator>::Item; 339 340 #[inline] into_iter(self) -> Self::IntoIter341 fn into_iter(self) -> Self::IntoIter { 342 self.as_bitslice().into_iter() 343 } 344 } 345 346 #[cfg(not(tarpaulin_include))] 347 impl<'a, O, V> IntoIterator for &'a mut BitArray<O, V> 348 where 349 O: 'a + BitOrder, 350 V: 'a + BitView + Sized, 351 { 352 type IntoIter = <&'a mut BitSlice<O, V::Store> as IntoIterator>::IntoIter; 353 type Item = <&'a mut BitSlice<O, V::Store> as IntoIterator>::Item; 354 355 #[inline] into_iter(self) -> Self::IntoIter356 fn into_iter(self) -> Self::IntoIter { 357 self.as_mut_bitslice().into_iter() 358 } 359 } 360 361 impl<O, V> Unpin for BitArray<O, V> 362 where 363 O: BitOrder, 364 V: BitView + Sized, 365 { 366 } 367 368 /// The error type returned when a conversion from a bitslice to a bitarray 369 /// fails. 370 #[derive(Clone, Copy, Debug)] 371 pub struct TryFromBitSliceError; 372 373 #[cfg(not(tarpaulin_include))] 374 impl TryFromBitSliceError { 375 #[inline(always)] err<T>() -> Result<T, Self>376 fn err<T>() -> Result<T, Self> { 377 Err(Self) 378 } 379 } 380 381 #[cfg(not(tarpaulin_include))] 382 impl Display for TryFromBitSliceError { 383 #[inline] fmt(&self, fmt: &mut Formatter) -> fmt::Result384 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { 385 fmt.write_str("could not convert bitslice to bitarray") 386 } 387 } 388 389 #[cfg(feature = "std")] 390 impl std::error::Error for TryFromBitSliceError { 391 } 392 393 #[cfg(test)] 394 mod tests { 395 use crate::prelude::*; 396 use core::convert::TryInto; 397 398 #[test] convert()399 fn convert() { 400 let arr: BitArray<Lsb0, _> = 2u8.into(); 401 assert!(arr.any()); 402 403 let bits = bits![1; 128]; 404 let arr: BitArray<Msb0, [u16; 8]> = bits.try_into().unwrap(); 405 assert!(arr.all()); 406 407 let bits = bits![Lsb0, u32; 0; 64]; 408 let arr: &BitArray<Lsb0, [u32; 2]> = bits.try_into().unwrap(); 409 assert!(arr.not_any()); 410 411 let bits = bits![mut Msb0, u16; 0; 64]; 412 let arr: &mut BitArray<Msb0, [u16; 4]> = bits.try_into().unwrap(); 413 assert!(arr.not_any()); 414 415 let bits = bits![mut 0; 4]; 416 let bit_arr: Result<&BitArray<LocalBits, usize>, _> = 417 (&*bits).try_into(); 418 assert!(bit_arr.is_err()); 419 let bit_arr: Result<&mut BitArray<LocalBits, usize>, _> = 420 bits.try_into(); 421 assert!(bit_arr.is_err()); 422 } 423 424 #[test] 425 #[cfg(feature = "std")] format()426 fn format() { 427 let render = format!("{:#?}", bitarr![Msb0, u8; 0, 1, 0, 0]); 428 assert!( 429 render.starts_with("BitArray<bitvec::order::Msb0, u8> {"), 430 "{}", 431 render 432 ); 433 assert!( 434 render.ends_with( 435 " head: 000,\n bits: 8,\n} [\n 0b01000000,\n]" 436 ), 437 "{}", 438 render 439 ); 440 } 441 } 442