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 fn contains_all<R: RangeBounds<u32>>(&self, values: R) -> bool {
356 match self {
357 CowSplinter::Ref(splinter_ref) => splinter_ref.contains_all(values),
358 CowSplinter::Owned(splinter) => splinter.contains_all(values),
359 }
360 }
361
362 fn contains_any<R: RangeBounds<u32>>(&self, values: R) -> bool {
363 match self {
364 CowSplinter::Ref(splinter_ref) => splinter_ref.contains_any(values),
365 CowSplinter::Owned(splinter) => splinter.contains_any(values),
366 }
367 }
368}
369
370impl<B: Deref<Target = [u8]>> PartitionWrite<High> for CowSplinter<B> {
371 #[inline]
372 fn insert(&mut self, value: u32) -> bool {
373 self.to_mut().insert(value)
374 }
375
376 #[inline]
377 fn remove(&mut self, value: u32) -> bool {
378 self.to_mut().remove(value)
379 }
380
381 #[inline]
382 fn remove_range<R: RangeBounds<u32>>(&mut self, values: R) {
383 self.to_mut().remove_range(values)
384 }
385}
386
387impl<B: Deref<Target = [u8]>, B2: Deref<Target = [u8]>> PartialEq<CowSplinter<B2>>
388 for CowSplinter<B>
389{
390 fn eq(&self, other: &CowSplinter<B2>) -> bool {
391 use CowSplinter::*;
392 match (self, other) {
393 (Ref(l), Ref(r)) => l == r,
394 (Ref(l), Owned(r)) => l == r,
395 (Owned(l), Ref(r)) => l == r,
396 (Owned(l), Owned(r)) => l == r,
397 }
398 }
399}
400
401impl<B: Deref<Target = [u8]>> Eq for CowSplinter<B> {}
402
403impl<B: Deref<Target = [u8]>> PartialEq<Splinter> for CowSplinter<B> {
404 fn eq(&self, other: &Splinter) -> bool {
405 other == self
406 }
407}
408
409impl<B: Deref<Target = [u8]>, B2: Deref<Target = [u8]>> PartialEq<SplinterRef<B2>>
410 for CowSplinter<B>
411{
412 fn eq(&self, other: &SplinterRef<B2>) -> bool {
413 match self {
414 CowSplinter::Ref(splinter_ref) => splinter_ref == other,
415 CowSplinter::Owned(splinter) => splinter == other,
416 }
417 }
418}
419
420macro_rules! owned_bitop {
421 ($b:ty $([$($for:tt)*])?) => {
422 owned_bitop!($b $([$($for)*])?, BitAnd, bitand, BitAndAssign::bitand_assign);
423 owned_bitop!($b $([$($for)*])?, BitOr, bitor, BitOrAssign::bitor_assign);
424 owned_bitop!($b $([$($for)*])?, BitXor, bitxor, BitXorAssign::bitxor_assign);
425 owned_bitop!($b $([$($for)*])?, Sub, sub, SubAssign::sub_assign);
426 };
427 ($b:ty $([$($for:tt)*])?, $BitOp:ident, $bitop:ident, $bitassign:path) => {
428 impl<B1: Deref<Target = [u8]> $(, $($for)*)?> $BitOp<$b> for CowSplinter<B1> {
429 type Output = Self;
430 fn $bitop(mut self, rhs: $b) -> Self::Output {
431 $bitassign(self.to_mut(), rhs);
432 self
433 }
434 }
435 };
436}
437
438owned_bitop!(Splinter);
439owned_bitop!(&Splinter);
440owned_bitop!(SplinterRef<B2> [B2: Deref<Target=[u8]>]);
441owned_bitop!(&SplinterRef<B2> [B2: Deref<Target=[u8]>]);
442owned_bitop!(CowSplinter<B2> [B2: Deref<Target=[u8]>]);
443owned_bitop!(&CowSplinter<B2> [B2: Deref<Target=[u8]>]);
444
445macro_rules! ref_bitop {
446 ($b:ty $([$($for:tt)*])?) => {
447 ref_bitop!($b $([$($for)*])?, BitAnd, bitand, BitAndAssign::bitand_assign);
448 ref_bitop!($b $([$($for)*])?, BitOr, bitor, BitOrAssign::bitor_assign);
449 ref_bitop!($b $([$($for)*])?, BitXor, bitxor, BitXorAssign::bitxor_assign);
450 ref_bitop!($b $([$($for)*])?, Sub, sub, SubAssign::sub_assign);
451 };
452 ($b:ty $([$($for:tt)*])?, $BitOp:ident, $bitop:ident, $bitassign:path) => {
453 impl<B1: Deref<Target = [u8]> + Clone $(, $($for)*)?> $BitOp<$b>
454 for &CowSplinter<B1>
455 {
456 type Output = CowSplinter<B1>;
457 fn $bitop(self, rhs: $b) -> Self::Output {
458 let mut out = self.clone();
459 $bitassign(out.to_mut(), rhs);
460 out
461 }
462 }
463 };
464}
465
466ref_bitop!(Splinter);
467ref_bitop!(&Splinter);
468ref_bitop!(SplinterRef<B2> [B2: Deref<Target=[u8]>]);
469ref_bitop!(&SplinterRef<B2> [B2: Deref<Target=[u8]>]);
470ref_bitop!(CowSplinter<B2> [B2: Deref<Target=[u8]>]);
471ref_bitop!(&CowSplinter<B2> [B2: Deref<Target=[u8]>]);