splinter_rs/
cow.rs

1use std::fmt::Debug;
2
3use bytes::Bytes;
4use culprit::Culprit;
5use either::Either;
6
7use crate::{DecodeErr, Splinter, SplinterRead, SplinterRef, SplinterWrite, util::CopyToOwned};
8
9// A Clone-on-write Splinter
10#[derive(Clone)]
11pub enum CowSplinter<B> {
12    Ref(SplinterRef<B>),
13    Owned(Splinter),
14}
15
16impl<B> Default for CowSplinter<B> {
17    fn default() -> Self {
18        Self::Owned(Splinter::default())
19    }
20}
21
22impl<B: AsRef<[u8]>> Debug for CowSplinter<B> {
23    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24        match self {
25            CowSplinter::Ref(splinter_ref) => splinter_ref.fmt(f),
26            CowSplinter::Owned(splinter) => splinter.fmt(f),
27        }
28    }
29}
30
31impl<B, K: Into<u32>> FromIterator<K> for CowSplinter<B>
32where
33    B: AsRef<[u8]>,
34{
35    fn from_iter<I: IntoIterator<Item = K>>(iter: I) -> Self {
36        Self::Owned(Splinter::from_iter(iter))
37    }
38}
39
40impl<B> From<Splinter> for CowSplinter<B> {
41    fn from(splinter: Splinter) -> Self {
42        Self::Owned(splinter)
43    }
44}
45
46impl<B> From<SplinterRef<B>> for CowSplinter<B> {
47    fn from(splinter_ref: SplinterRef<B>) -> Self {
48        Self::Ref(splinter_ref)
49    }
50}
51
52impl<B: AsRef<[u8]>> From<CowSplinter<B>> for Splinter {
53    fn from(cow_splinter: CowSplinter<B>) -> Self {
54        cow_splinter.into_owned()
55    }
56}
57
58impl From<CowSplinter<Bytes>> for SplinterRef<Bytes> {
59    fn from(cow: CowSplinter<Bytes>) -> Self {
60        match cow {
61            CowSplinter::Ref(splinter_ref) => splinter_ref,
62            CowSplinter::Owned(splinter) => splinter.serialize_to_splinter_ref(),
63        }
64    }
65}
66
67impl<B> CowSplinter<B> {
68    pub fn from_owned(splinter: Splinter) -> Self {
69        Self::Owned(splinter)
70    }
71
72    pub fn from_ref(splinter: SplinterRef<B>) -> Self {
73        Self::Ref(splinter)
74    }
75}
76
77impl<B: AsRef<[u8]>> CowSplinter<B> {
78    pub fn from_bytes(data: B) -> Result<Self, Culprit<DecodeErr>> {
79        Ok(Self::Ref(SplinterRef::from_bytes(data)?))
80    }
81
82    pub fn into_owned(self) -> Splinter {
83        match self {
84            Self::Ref(splinter_ref) => splinter_ref.copy_to_owned(),
85            Self::Owned(splinter) => splinter,
86        }
87    }
88
89    pub fn to_mut(&mut self) -> &mut Splinter {
90        match *self {
91            Self::Ref(ref splinter_ref) => {
92                *self = Self::Owned(splinter_ref.copy_to_owned());
93                match *self {
94                    Self::Ref(..) => unreachable!(),
95                    Self::Owned(ref mut owned) => owned,
96                }
97            }
98            Self::Owned(ref mut owned) => owned,
99        }
100    }
101
102    pub fn serialized_size(&self) -> usize {
103        match self {
104            CowSplinter::Ref(splinter_ref) => splinter_ref.size(),
105            CowSplinter::Owned(splinter) => splinter.serialized_size(),
106        }
107    }
108
109    pub fn serialize<T: bytes::BufMut>(&self, out: &mut T) -> usize {
110        match self {
111            CowSplinter::Ref(splinter_ref) => {
112                out.put_slice(splinter_ref.inner().as_ref());
113                splinter_ref.size()
114            }
115            CowSplinter::Owned(splinter) => splinter.serialize(out),
116        }
117    }
118}
119
120impl CowSplinter<Bytes> {
121    pub fn serialize_into_bytes<T: bytes::BufMut>(&self, out: &mut T) -> usize {
122        match self {
123            CowSplinter::Ref(splinter_ref) => {
124                out.put(splinter_ref.inner().clone());
125                splinter_ref.size()
126            }
127            CowSplinter::Owned(splinter) => splinter.serialize(out),
128        }
129    }
130
131    pub fn serialize_to_bytes(&self) -> Bytes {
132        match self {
133            CowSplinter::Ref(splinter_ref) => splinter_ref.inner().clone(),
134            CowSplinter::Owned(splinter) => splinter.serialize_to_bytes(),
135        }
136    }
137}
138
139impl<B: AsRef<[u8]>> SplinterRead for CowSplinter<B> {
140    fn is_empty(&self) -> bool {
141        match self {
142            CowSplinter::Ref(splinter) => splinter.is_empty(),
143            CowSplinter::Owned(splinter) => splinter.is_empty(),
144        }
145    }
146
147    fn contains(&self, key: u32) -> bool {
148        match self {
149            CowSplinter::Ref(splinter) => splinter.contains(key),
150            CowSplinter::Owned(splinter) => splinter.contains(key),
151        }
152    }
153
154    fn cardinality(&self) -> usize {
155        match self {
156            CowSplinter::Ref(splinter) => splinter.cardinality(),
157            CowSplinter::Owned(splinter) => splinter.cardinality(),
158        }
159    }
160
161    fn iter(&self) -> impl Iterator<Item = u32> + '_ {
162        match self {
163            CowSplinter::Ref(splinter) => Either::Left(splinter.iter()),
164            CowSplinter::Owned(splinter) => Either::Right(splinter.iter()),
165        }
166    }
167
168    fn range<'a, R>(&'a self, range: R) -> impl Iterator<Item = u32> + 'a
169    where
170        R: std::ops::RangeBounds<u32> + 'a,
171    {
172        match self {
173            CowSplinter::Ref(splinter) => Either::Left(splinter.range(range)),
174            CowSplinter::Owned(splinter) => Either::Right(splinter.range(range)),
175        }
176    }
177
178    fn last(&self) -> Option<u32> {
179        match self {
180            CowSplinter::Ref(splinter) => splinter.last(),
181            CowSplinter::Owned(splinter) => splinter.last(),
182        }
183    }
184}
185
186impl<B: AsRef<[u8]>> SplinterWrite for CowSplinter<B> {
187    /// Inserts a key into the splinter, converting it to an owned version if it was a reference.
188    fn insert(&mut self, key: u32) -> bool {
189        self.to_mut().insert(key)
190    }
191}