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#[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 fn insert(&mut self, key: u32) -> bool {
189 self.to_mut().insert(key)
190 }
191}