Coverage Report

Created: 2025-07-18 06:16

/rust/registry/src/index.crates.io-6f17d22bba15001f/bitvec-1.0.1/src/array/traits.rs
Line
Count
Source (jump to first uncovered line)
1
//! Additional trait implementations on bit-arrays.
2
3
use core::{
4
  borrow::{
5
    Borrow,
6
    BorrowMut,
7
  },
8
  cmp,
9
  convert::TryFrom,
10
  fmt::{
11
    self,
12
    Debug,
13
    Display,
14
    Formatter,
15
  },
16
  hash::{
17
    Hash,
18
    Hasher,
19
  },
20
  marker::Unpin,
21
};
22
23
use tap::TryConv;
24
25
use super::BitArray;
26
use crate::{
27
  index::BitIdx,
28
  mem,
29
  order::BitOrder,
30
  slice::BitSlice,
31
  store::BitStore,
32
  view::BitViewSized,
33
};
34
35
#[cfg(not(tarpaulin_include))]
36
impl<A, O> Borrow<BitSlice<A::Store, O>> for BitArray<A, O>
37
where
38
  A: BitViewSized,
39
  O: BitOrder,
40
{
41
  #[inline]
42
0
  fn borrow(&self) -> &BitSlice<A::Store, O> {
43
0
    self.as_bitslice()
44
0
  }
45
}
46
47
#[cfg(not(tarpaulin_include))]
48
impl<A, O> BorrowMut<BitSlice<A::Store, O>> for BitArray<A, O>
49
where
50
  A: BitViewSized,
51
  O: BitOrder,
52
{
53
  #[inline]
54
0
  fn borrow_mut(&mut self) -> &mut BitSlice<A::Store, O> {
55
0
    self.as_mut_bitslice()
56
0
  }
57
}
58
59
impl<A, O> Clone for BitArray<A, O>
60
where
61
  A: BitViewSized,
62
  O: BitOrder,
63
{
64
  #[inline]
65
0
  fn clone(&self) -> Self {
66
0
    let mut out = Self::ZERO;
67
0
    for (dst, src) in
68
0
      out.as_raw_mut_slice().iter_mut().zip(self.as_raw_slice())
69
0
    {
70
0
      dst.store_value(src.load_value());
71
0
    }
72
0
    out
73
0
  }
74
}
75
76
impl<A, O> Eq for BitArray<A, O>
77
where
78
  A: BitViewSized,
79
  O: BitOrder,
80
{
81
}
82
83
#[cfg(not(tarpaulin_include))]
84
impl<A, O> Ord for BitArray<A, O>
85
where
86
  A: BitViewSized,
87
  O: BitOrder,
88
{
89
  #[inline]
90
0
  fn cmp(&self, other: &Self) -> cmp::Ordering {
91
0
    self.as_bitslice().cmp(other.as_bitslice())
92
0
  }
93
}
94
95
#[cfg(not(tarpaulin_include))]
96
impl<O1, A, O2, T> PartialEq<BitArray<A, O2>> for BitSlice<T, O1>
97
where
98
  O1: BitOrder,
99
  O2: BitOrder,
100
  A: BitViewSized,
101
  T: BitStore,
102
{
103
  #[inline]
104
0
  fn eq(&self, other: &BitArray<A, O2>) -> bool {
105
0
    self == other.as_bitslice()
106
0
  }
107
}
108
109
#[cfg(not(tarpaulin_include))]
110
impl<A, O, Rhs> PartialEq<Rhs> for BitArray<A, O>
111
where
112
  A: BitViewSized,
113
  O: BitOrder,
114
  Rhs: ?Sized,
115
  BitSlice<A::Store, O>: PartialEq<Rhs>,
116
{
117
  #[inline]
118
0
  fn eq(&self, other: &Rhs) -> bool {
119
0
    self.as_bitslice() == other
120
0
  }
121
}
122
123
#[cfg(not(tarpaulin_include))]
124
impl<A, T, O> PartialOrd<BitArray<A, O>> for BitSlice<T, O>
125
where
126
  A: BitViewSized,
127
  T: BitStore,
128
  O: BitOrder,
129
{
130
  #[inline]
131
0
  fn partial_cmp(&self, other: &BitArray<A, O>) -> Option<cmp::Ordering> {
132
0
    self.partial_cmp(other.as_bitslice())
133
0
  }
134
}
135
136
#[cfg(not(tarpaulin_include))]
137
impl<A, O, Rhs> PartialOrd<Rhs> for BitArray<A, O>
138
where
139
  A: BitViewSized,
140
  O: BitOrder,
141
  Rhs: ?Sized,
142
  BitSlice<A::Store, O>: PartialOrd<Rhs>,
143
{
144
  #[inline]
145
0
  fn partial_cmp(&self, other: &Rhs) -> Option<cmp::Ordering> {
146
0
    self.as_bitslice().partial_cmp(other)
147
0
  }
148
}
149
150
#[cfg(not(tarpaulin_include))]
151
impl<A, O> AsRef<BitSlice<A::Store, O>> for BitArray<A, O>
152
where
153
  A: BitViewSized,
154
  O: BitOrder,
155
{
156
  #[inline]
157
0
  fn as_ref(&self) -> &BitSlice<A::Store, O> {
158
0
    self.as_bitslice()
159
0
  }
160
}
161
162
#[cfg(not(tarpaulin_include))]
163
impl<A, O> AsMut<BitSlice<A::Store, O>> for BitArray<A, O>
164
where
165
  A: BitViewSized,
166
  O: BitOrder,
167
{
168
  #[inline]
169
0
  fn as_mut(&mut self) -> &mut BitSlice<A::Store, O> {
170
0
    self.as_mut_bitslice()
171
0
  }
172
}
173
174
#[cfg(not(tarpaulin_include))]
175
impl<A, O> From<A> for BitArray<A, O>
176
where
177
  A: BitViewSized,
178
  O: BitOrder,
179
{
180
  #[inline]
181
0
  fn from(data: A) -> Self {
182
0
    Self::new(data)
183
0
  }
184
}
185
186
impl<A, O> TryFrom<&BitSlice<A::Store, O>> for BitArray<A, O>
187
where
188
  A: BitViewSized,
189
  O: BitOrder,
190
{
191
  type Error = TryFromBitSliceError;
192
193
  #[inline]
194
0
  fn try_from(src: &BitSlice<A::Store, O>) -> Result<Self, Self::Error> {
195
0
    src.try_conv::<&Self>().map(|this| this.clone())
196
0
  }
197
}
198
199
impl<A, O> TryFrom<&BitSlice<A::Store, O>> for &BitArray<A, O>
200
where
201
  A: BitViewSized,
202
  O: BitOrder,
203
{
204
  type Error = TryFromBitSliceError;
205
206
  #[inline]
207
0
  fn try_from(src: &BitSlice<A::Store, O>) -> Result<Self, Self::Error> {
208
0
    TryFromBitSliceError::new::<A, O>(src).map(|()| unsafe {
209
0
      &*src
210
0
        .as_bitspan()
211
0
        .address()
212
0
        .to_const()
213
0
        .cast::<BitArray<A, O>>()
214
0
    })
215
0
  }
216
}
217
218
impl<A, O> TryFrom<&mut BitSlice<A::Store, O>> for &mut BitArray<A, O>
219
where
220
  A: BitViewSized,
221
  O: BitOrder,
222
{
223
  type Error = TryFromBitSliceError;
224
225
  #[inline]
226
0
  fn try_from(src: &mut BitSlice<A::Store, O>) -> Result<Self, Self::Error> {
227
0
    TryFromBitSliceError::new::<A, O>(src).map(|()| unsafe {
228
0
      &mut *src
229
0
        .as_mut_bitspan()
230
0
        .address()
231
0
        .to_mut()
232
0
        .cast::<BitArray<A, O>>()
233
0
    })
234
0
  }
235
}
236
237
impl<A, O> Default for BitArray<A, O>
238
where
239
  A: BitViewSized,
240
  O: BitOrder,
241
{
242
  #[inline]
243
0
  fn default() -> Self {
244
0
    Self::ZERO
245
0
  }
246
}
247
248
impl<A, O> Debug for BitArray<A, O>
249
where
250
  A: BitViewSized,
251
  O: BitOrder,
252
{
253
  #[inline]
254
0
  fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
255
0
    self.as_bitspan().render(fmt, "Array", None)?;
256
0
    fmt.write_str(" ")?;
257
0
    Display::fmt(self, fmt)
258
0
  }
259
}
260
261
easy_fmt! {
262
  impl Binary
263
  impl Display
264
  impl LowerHex
265
  impl Octal
266
  impl UpperHex
267
  for BitArray
268
}
269
270
#[cfg(not(tarpaulin_include))]
271
impl<A, O> Hash for BitArray<A, O>
272
where
273
  A: BitViewSized,
274
  O: BitOrder,
275
{
276
  #[inline]
277
0
  fn hash<H>(&self, hasher: &mut H)
278
0
  where H: Hasher {
279
0
    self.as_bitslice().hash(hasher);
280
0
  }
281
}
282
283
impl<A, O> Copy for BitArray<A, O>
284
where
285
  O: BitOrder,
286
  A: BitViewSized + Copy,
287
{
288
}
289
290
impl<A, O> Unpin for BitArray<A, O>
291
where
292
  A: BitViewSized,
293
  O: BitOrder,
294
{
295
}
296
297
#[repr(transparent)]
298
#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
299
#[doc = include_str!("../../doc/array/TryFromBitSliceError.md")]
300
pub struct TryFromBitSliceError(InnerError);
301
302
impl TryFromBitSliceError {
303
  /// Checks whether a bit-slice can be viewed as a bit-array.
304
  #[inline]
305
0
  fn new<A, O>(bits: &BitSlice<A::Store, O>) -> Result<(), Self>
306
0
  where
307
0
    O: BitOrder,
308
0
    A: BitViewSized,
309
0
  {
310
0
    InnerError::new::<A, O>(bits).map_err(Self)
311
0
  }
312
}
313
314
impl Debug for TryFromBitSliceError {
315
  #[inline]
316
0
  fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
317
0
    fmt.write_str("TryFromBitSliceError::")?;
318
0
    match self.0 {
319
0
      InnerError::UnequalLen { actual, expected } => {
320
0
        write!(fmt, "UnequalLen({} != {})", actual, expected)
321
      },
322
0
      InnerError::Misaligned => fmt.write_str("Misaligned"),
323
    }
324
0
  }
325
}
326
327
#[cfg(not(tarpaulin_include))]
328
impl Display for TryFromBitSliceError {
329
  #[inline]
330
0
  fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
331
0
    match self.0 {
332
0
      InnerError::UnequalLen { actual, expected } => write!(
333
0
        fmt,
334
0
        "bit-slice with length {} cannot be viewed as bit-array with \
335
0
         length {}",
336
0
        actual, expected,
337
0
      ),
338
0
      InnerError::Misaligned => fmt.write_str(
339
0
        "a bit-slice must begin at the front edge of a storage element \
340
0
         in order to be viewed as a bit-array",
341
0
      ),
342
    }
343
0
  }
344
}
345
346
#[cfg(feature = "std")]
347
impl std::error::Error for TryFromBitSliceError {}
348
349
/// Opaque error type for bit-slice to bit-array view conversions.
350
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
351
enum InnerError {
352
  /// A bit-slice did not match the length of the destination bit-array.
353
  UnequalLen {
354
    /// The length of the bit-slice that produced this error.
355
    actual:   usize,
356
    /// The length of the destination bit-array type.
357
    expected: usize,
358
  },
359
  /// A bit-slice did not begin at `BitIdx::MIN`.
360
  Misaligned,
361
}
362
363
impl InnerError {
364
  /// Checks whether a bit-slice is suitable to view as a bit-array.
365
  #[inline]
366
0
  fn new<A, O>(bits: &BitSlice<A::Store, O>) -> Result<(), Self>
367
0
  where
368
0
    O: BitOrder,
369
0
    A: BitViewSized,
370
0
  {
371
0
    let bitspan = bits.as_bitspan();
372
0
    let actual = bitspan.len();
373
0
    let expected = mem::bits_of::<A>();
374
0
    if actual != expected {
375
0
      return Err(Self::UnequalLen { actual, expected });
376
0
    }
377
0
    if bitspan.head() != BitIdx::<<A::Store as BitStore>::Mem>::MIN {
378
0
      return Err(Self::Misaligned);
379
0
    }
380
0
    Ok(())
381
0
  }
382
}