1use std::fmt::Debug;
2use std::ops::{
3 BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Deref, RangeBounds, Sub,
4 SubAssign,
5};
6
7use bytes::{BufMut, Bytes};
8use culprit::Culprit;
9use either::Either;
10
11use crate::{
12 Encodable, PartitionRead, PartitionWrite, Splinter, SplinterRef,
13 codec::{DecodeErr, encoder::Encoder},
14 level::High,
15};
16
17#[derive(Clone)]
68pub enum CowSplinter<B> {
69 Ref(SplinterRef<B>),
71 Owned(Splinter),
73}
74
75impl<B> Default for CowSplinter<B> {
76 fn default() -> Self {
77 Self::Owned(Splinter::EMPTY)
78 }
79}
80
81impl<B: Deref<Target = [u8]>> Debug for CowSplinter<B> {
82 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83 match self {
84 CowSplinter::Ref(splinter_ref) => f
85 .debug_tuple("CowSplinter::Ref")
86 .field(splinter_ref)
87 .finish(),
88 CowSplinter::Owned(splinter) => {
89 f.debug_tuple("CowSplinter::Owned").field(splinter).finish()
90 }
91 }
92 }
93}
94
95impl<B, K: Into<u32>> FromIterator<K> for CowSplinter<B>
96where
97 B: Deref<Target = [u8]>,
98{
99 fn from_iter<I: IntoIterator<Item = K>>(iter: I) -> Self {
100 Self::Owned(Splinter::from_iter(iter.into_iter().map(|k| k.into())))
101 }
102}
103
104impl<B> From<Splinter> for CowSplinter<B> {
105 fn from(splinter: Splinter) -> Self {
106 Self::Owned(splinter)
107 }
108}
109
110impl<B> From<SplinterRef<B>> for CowSplinter<B> {
111 fn from(splinter_ref: SplinterRef<B>) -> Self {
112 Self::Ref(splinter_ref)
113 }
114}
115
116impl<B: Deref<Target = [u8]>> From<CowSplinter<B>> for Splinter {
117 fn from(cow_splinter: CowSplinter<B>) -> Self {
118 cow_splinter.into_owned()
119 }
120}
121
122impl From<CowSplinter<Bytes>> for SplinterRef<Bytes> {
123 fn from(cow: CowSplinter<Bytes>) -> Self {
124 match cow {
125 CowSplinter::Ref(splinter_ref) => splinter_ref,
126 CowSplinter::Owned(splinter) => splinter.encode_to_splinter_ref(),
127 }
128 }
129}
130
131impl<B> CowSplinter<B> {
132 pub fn from_owned(splinter: Splinter) -> Self {
144 splinter.into()
145 }
146
147 pub fn from_ref(splinter: SplinterRef<B>) -> Self {
162 splinter.into()
163 }
164}
165
166impl<B: Deref<Target = [u8]>> CowSplinter<B> {
167 pub fn from_bytes(data: B) -> Result<Self, Culprit<DecodeErr>> {
189 Ok(Self::Ref(SplinterRef::from_bytes(data)?))
190 }
191
192 pub fn into_owned(self) -> Splinter {
212 match self {
213 Self::Ref(splinter_ref) => splinter_ref.decode_to_splinter(),
214 Self::Owned(splinter) => splinter,
215 }
216 }
217
218 pub fn to_mut(&mut self) -> &mut Splinter {
242 match *self {
243 Self::Ref(ref splinter_ref) => {
244 *self = Self::Owned(splinter_ref.decode_to_splinter());
245 match *self {
246 Self::Ref(..) => unreachable!(),
247 Self::Owned(ref mut owned) => owned,
248 }
249 }
250 Self::Owned(ref mut owned) => owned,
251 }
252 }
253}
254
255impl CowSplinter<Bytes> {
256 pub fn encode_to_bytes(&self) -> Bytes {
275 match self {
276 CowSplinter::Ref(splinter_ref) => splinter_ref.encode_to_bytes(),
277 CowSplinter::Owned(splinter) => splinter.encode_to_bytes(),
278 }
279 }
280}
281
282impl<B: Deref<Target = [u8]>> Encodable for CowSplinter<B> {
283 fn encoded_size(&self) -> usize {
284 match self {
285 CowSplinter::Ref(splinter_ref) => splinter_ref.encoded_size(),
286 CowSplinter::Owned(splinter) => splinter.encoded_size(),
287 }
288 }
289
290 fn encode<T: BufMut>(&self, encoder: &mut Encoder<T>) {
291 match self {
292 CowSplinter::Ref(splinter_ref) => splinter_ref.encode(encoder),
293 CowSplinter::Owned(splinter) => splinter.encode(encoder),
294 }
295 }
296}
297
298impl<B: Deref<Target = [u8]>> PartitionRead<High> for CowSplinter<B> {
299 fn cardinality(&self) -> usize {
300 match self {
301 CowSplinter::Ref(splinter_ref) => splinter_ref.cardinality(),
302 CowSplinter::Owned(splinter) => splinter.cardinality(),
303 }
304 }
305
306 fn is_empty(&self) -> bool {
307 match self {
308 CowSplinter::Ref(splinter_ref) => splinter_ref.is_empty(),
309 CowSplinter::Owned(splinter) => splinter.is_empty(),
310 }
311 }
312
313 fn contains(&self, value: u32) -> bool {
314 match self {
315 CowSplinter::Ref(splinter_ref) => splinter_ref.contains(value),
316 CowSplinter::Owned(splinter) => splinter.contains(value),
317 }
318 }
319
320 fn position(&self, value: u32) -> Option<usize> {
321 match self {
322 CowSplinter::Ref(splinter_ref) => splinter_ref.position(value),
323 CowSplinter::Owned(splinter) => splinter.position(value),
324 }
325 }
326
327 fn rank(&self, value: u32) -> usize {
328 match self {
329 CowSplinter::Ref(splinter_ref) => splinter_ref.rank(value),
330 CowSplinter::Owned(splinter) => splinter.rank(value),
331 }
332 }
333
334 fn select(&self, idx: usize) -> Option<u32> {
335 match self {
336 CowSplinter::Ref(splinter_ref) => splinter_ref.select(idx),
337 CowSplinter::Owned(splinter) => splinter.select(idx),
338 }
339 }
340
341 fn last(&self) -> Option<u32> {
342 match self {
343 CowSplinter::Ref(splinter_ref) => splinter_ref.last(),
344 CowSplinter::Owned(splinter) => splinter.last(),
345 }
346 }
347
348 fn iter(&self) -> impl Iterator<Item = u32> {
349 match self {
350 CowSplinter::Ref(splinter_ref) => Either::Left(splinter_ref.iter()),
351 CowSplinter::Owned(splinter) => Either::Right(splinter.iter()),
352 }
353 }
354}
355
356impl<B: Deref<Target = [u8]>> PartitionWrite<High> for CowSplinter<B> {
357 #[inline]
358 fn insert(&mut self, value: u32) -> bool {
359 self.to_mut().insert(value)
360 }
361
362 #[inline]
363 fn remove(&mut self, value: u32) -> bool {
364 self.to_mut().remove(value)
365 }
366
367 #[inline]
368 fn remove_range<R: RangeBounds<u32>>(&mut self, values: R) {
369 self.to_mut().remove_range(values)
370 }
371}
372
373impl<B: Deref<Target = [u8]>, B2: Deref<Target = [u8]>> PartialEq<CowSplinter<B2>>
374 for CowSplinter<B>
375{
376 fn eq(&self, other: &CowSplinter<B2>) -> bool {
377 use CowSplinter::*;
378 match (self, other) {
379 (Ref(l), Ref(r)) => l == r,
380 (Ref(l), Owned(r)) => l == r,
381 (Owned(l), Ref(r)) => l == r,
382 (Owned(l), Owned(r)) => l == r,
383 }
384 }
385}
386
387impl<B: Deref<Target = [u8]>> Eq for CowSplinter<B> {}
388
389impl<B: Deref<Target = [u8]>> PartialEq<Splinter> for CowSplinter<B> {
390 fn eq(&self, other: &Splinter) -> bool {
391 other == self
392 }
393}
394
395impl<B: Deref<Target = [u8]>, B2: Deref<Target = [u8]>> PartialEq<SplinterRef<B2>>
396 for CowSplinter<B>
397{
398 fn eq(&self, other: &SplinterRef<B2>) -> bool {
399 match self {
400 CowSplinter::Ref(splinter_ref) => splinter_ref == other,
401 CowSplinter::Owned(splinter) => splinter == other,
402 }
403 }
404}
405
406macro_rules! owned_bitop {
407 ($b:ty $([$($for:tt)*])?) => {
408 owned_bitop!($b $([$($for)*])?, BitAnd, bitand, BitAndAssign::bitand_assign);
409 owned_bitop!($b $([$($for)*])?, BitOr, bitor, BitOrAssign::bitor_assign);
410 owned_bitop!($b $([$($for)*])?, BitXor, bitxor, BitXorAssign::bitxor_assign);
411 owned_bitop!($b $([$($for)*])?, Sub, sub, SubAssign::sub_assign);
412 };
413 ($b:ty $([$($for:tt)*])?, $BitOp:ident, $bitop:ident, $bitassign:path) => {
414 impl<B1: Deref<Target = [u8]> $(, $($for)*)?> $BitOp<$b> for CowSplinter<B1> {
415 type Output = Self;
416 fn $bitop(mut self, rhs: $b) -> Self::Output {
417 $bitassign(self.to_mut(), rhs);
418 self
419 }
420 }
421 };
422}
423
424owned_bitop!(Splinter);
425owned_bitop!(&Splinter);
426owned_bitop!(SplinterRef<B2> [B2: Deref<Target=[u8]>]);
427owned_bitop!(&SplinterRef<B2> [B2: Deref<Target=[u8]>]);
428owned_bitop!(CowSplinter<B2> [B2: Deref<Target=[u8]>]);
429owned_bitop!(&CowSplinter<B2> [B2: Deref<Target=[u8]>]);
430
431macro_rules! ref_bitop {
432 ($b:ty $([$($for:tt)*])?) => {
433 ref_bitop!($b $([$($for)*])?, BitAnd, bitand, BitAndAssign::bitand_assign);
434 ref_bitop!($b $([$($for)*])?, BitOr, bitor, BitOrAssign::bitor_assign);
435 ref_bitop!($b $([$($for)*])?, BitXor, bitxor, BitXorAssign::bitxor_assign);
436 ref_bitop!($b $([$($for)*])?, Sub, sub, SubAssign::sub_assign);
437 };
438 ($b:ty $([$($for:tt)*])?, $BitOp:ident, $bitop:ident, $bitassign:path) => {
439 impl<B1: Deref<Target = [u8]> + Clone $(, $($for)*)?> $BitOp<$b>
440 for &CowSplinter<B1>
441 {
442 type Output = CowSplinter<B1>;
443 fn $bitop(self, rhs: $b) -> Self::Output {
444 let mut out = self.clone();
445 $bitassign(out.to_mut(), rhs);
446 out
447 }
448 }
449 };
450}
451
452ref_bitop!(Splinter);
453ref_bitop!(&Splinter);
454ref_bitop!(SplinterRef<B2> [B2: Deref<Target=[u8]>]);
455ref_bitop!(&SplinterRef<B2> [B2: Deref<Target=[u8]>]);
456ref_bitop!(CowSplinter<B2> [B2: Deref<Target=[u8]>]);
457ref_bitop!(&CowSplinter<B2> [B2: Deref<Target=[u8]>]);