Skip to main content

reifydb_value/util/
cowvec.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use std::{borrow::Borrow, ops::Deref, sync::Arc, vec};
5
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7
8#[derive(Debug, PartialOrd, PartialEq, Ord, Eq, Hash)]
9pub struct CowVec<T>
10where
11	T: Clone + PartialEq,
12{
13	inner: Arc<Vec<T>>,
14}
15
16impl<T> CowVec<T>
17where
18	T: Clone + PartialEq,
19{
20	pub fn len(&self) -> usize {
21		self.inner.len()
22	}
23
24	pub fn is_empty(&self) -> bool {
25		self.inner.is_empty()
26	}
27}
28
29#[macro_export]
30macro_rules! cow_vec {
31    () => {
32        $crate::util::cowvec::CowVec::new(Vec::new())
33    };
34    ($($elem:expr),+ $(,)?) => {
35        $crate::util::cowvec::CowVec::new(vec![$($elem),+])
36    };
37}
38
39impl<T> Default for CowVec<T>
40where
41	T: Clone + PartialEq,
42{
43	fn default() -> Self {
44		Self {
45			inner: Arc::new(Vec::new()),
46		}
47	}
48}
49
50impl<T: Clone + PartialEq> PartialEq<[T]> for &CowVec<T> {
51	fn eq(&self, other: &[T]) -> bool {
52		self.inner.as_slice() == other
53	}
54}
55
56impl<T: Clone + PartialEq> PartialEq<[T]> for CowVec<T> {
57	fn eq(&self, other: &[T]) -> bool {
58		self.inner.as_slice() == other
59	}
60}
61
62impl<T: Clone + PartialEq> PartialEq<CowVec<T>> for [T] {
63	fn eq(&self, other: &CowVec<T>) -> bool {
64		self == other.inner.as_slice()
65	}
66}
67
68impl<T: Clone + PartialEq> Clone for CowVec<T> {
69	fn clone(&self) -> Self {
70		CowVec {
71			inner: Arc::clone(&self.inner),
72		}
73	}
74}
75
76impl<T: Clone + PartialEq> CowVec<T> {
77	pub fn new(vec: Vec<T>) -> Self {
78		CowVec {
79			inner: Arc::new(vec),
80		}
81	}
82
83	pub fn into_inner(self) -> Vec<T> {
84		match Arc::try_unwrap(self.inner) {
85			Ok(vec) => vec,
86			Err(arc) => (*arc).clone(),
87		}
88	}
89
90	pub fn as_slice(&self) -> &[T] {
91		&self.inner
92	}
93
94	pub fn make_mut(&mut self) -> &mut Vec<T> {
95		Arc::make_mut(&mut self.inner)
96	}
97}
98
99impl<T: Clone + PartialEq> IntoIterator for CowVec<T> {
100	type Item = T;
101	type IntoIter = vec::IntoIter<T>;
102
103	fn into_iter(self) -> Self::IntoIter {
104		match Arc::try_unwrap(self.inner) {
105			Ok(vec) => vec.into_iter(),
106			Err(arc) => (*arc).clone().into_iter(),
107		}
108	}
109}
110
111impl<T: Clone + PartialEq> Deref for CowVec<T> {
112	type Target = [T];
113
114	fn deref(&self) -> &Self::Target {
115		self.as_slice()
116	}
117}
118
119impl<T: Clone + PartialEq> Borrow<[T]> for CowVec<T> {
120	fn borrow(&self) -> &[T] {
121		self.as_slice()
122	}
123}
124
125impl<T> Serialize for CowVec<T>
126where
127	T: Clone + PartialEq + Serialize,
128{
129	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
130	where
131		S: Serializer,
132	{
133		self.inner.serialize(serializer)
134	}
135}
136
137impl<'de, T> Deserialize<'de> for CowVec<T>
138where
139	T: Clone + PartialEq + Deserialize<'de>,
140{
141	fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
142	where
143		D: Deserializer<'de>,
144	{
145		let vec = Vec::<T>::deserialize(deserializer)?;
146		Ok(CowVec {
147			inner: Arc::new(vec),
148		})
149	}
150}