Skip to content

Commit 9ed4581

Browse files
committed
Add implementations for smallvec and ringmap
1 parent fd75de5 commit 9ed4581

File tree

3 files changed

+189
-0
lines changed

3 files changed

+189
-0
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

turbopack/crates/turbo-bincode/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,7 @@ bincode = { workspace = true }
1515
either = { workspace = true }
1616
indexmap = { workspace = true }
1717
mime = { workspace = true }
18+
ringmap = { workspace = true }
1819
serde = { workspace = true }
1920
serde_json = { workspace = true }
21+
smallvec = { workspace = true }

turbopack/crates/turbo-bincode/src/lib.rs

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use ::smallvec::SmallVec;
12
use bincode::{
23
BorrowDecode, Decode, Encode,
34
de::{BorrowDecoder, Decoder},
@@ -162,6 +163,83 @@ pub mod indexset {
162163
}
163164
}
164165

166+
pub mod ringset {
167+
use std::hash::{BuildHasher, Hash};
168+
169+
use ::ringmap::RingSet;
170+
171+
use super::*;
172+
173+
pub fn encode<E, T, S>(set: &RingSet<T, S>, encoder: &mut E) -> Result<(), EncodeError>
174+
where
175+
E: Encoder,
176+
T: Encode,
177+
{
178+
usize::encode(&set.len(), encoder)?;
179+
for item in set {
180+
T::encode(item, encoder)?;
181+
}
182+
Ok(())
183+
}
184+
185+
pub fn decode<Context, D, T, S>(decoder: &mut D) -> Result<RingSet<T, S>, DecodeError>
186+
where
187+
D: Decoder<Context = Context>,
188+
T: Decode<Context> + Eq + Hash,
189+
S: BuildHasher + Default,
190+
{
191+
let len = usize::decode(decoder)?;
192+
let mut set = RingSet::with_capacity_and_hasher(len, Default::default());
193+
for _i in 0..len {
194+
set.insert(T::decode(decoder)?);
195+
}
196+
Ok(set)
197+
}
198+
199+
pub fn borrow_decode<'de, Context, D, T, S>(
200+
decoder: &mut D,
201+
) -> Result<RingSet<T, S>, DecodeError>
202+
where
203+
D: BorrowDecoder<'de, Context = Context>,
204+
T: BorrowDecode<'de, Context> + Eq + Hash,
205+
S: BuildHasher + Default,
206+
{
207+
let len = usize::decode(decoder)?;
208+
let mut set = RingSet::with_capacity_and_hasher(len, Default::default());
209+
for _i in 0..len {
210+
set.insert(T::borrow_decode(decoder)?);
211+
}
212+
Ok(set)
213+
}
214+
215+
#[cfg(test)]
216+
mod tests {
217+
use bincode::{decode_from_slice, encode_to_vec};
218+
219+
use super::*;
220+
221+
#[test]
222+
fn test_roundtrip() {
223+
let cfg = bincode::config::standard();
224+
225+
#[derive(Encode, Decode)]
226+
struct Wrapper(#[bincode(with = "crate::ringset")] RingSet<String>);
227+
228+
let set1 = Wrapper(RingSet::from([
229+
"value1".to_string(),
230+
"value2".to_string(),
231+
"value3".to_string(),
232+
]));
233+
234+
let set2: Wrapper = decode_from_slice(&encode_to_vec(&set1, cfg).unwrap(), cfg)
235+
.unwrap()
236+
.0;
237+
238+
assert_eq!(set1.0, set2.0);
239+
}
240+
}
241+
}
242+
165243
pub mod mime_option {
166244
use std::str::FromStr;
167245

@@ -381,3 +459,110 @@ pub mod either {
381459
}
382460
}
383461
}
462+
463+
pub mod smallvec {
464+
use ::smallvec::Array;
465+
466+
use super::*;
467+
468+
pub fn encode<E: Encoder, A: Array<Item = impl Encode>>(
469+
vec: &SmallVec<A>,
470+
encoder: &mut E,
471+
) -> Result<(), EncodeError> {
472+
usize::encode(&vec.len(), encoder)?;
473+
for item in vec {
474+
Encode::encode(item, encoder)?;
475+
}
476+
Ok(())
477+
}
478+
479+
pub fn decode<Context, D: Decoder<Context = Context>, A: Array<Item = impl Decode<Context>>>(
480+
decoder: &mut D,
481+
) -> Result<SmallVec<A>, DecodeError> {
482+
let len = usize::decode(decoder)?;
483+
let mut vec = SmallVec::with_capacity(len);
484+
for _ in 0..len {
485+
vec.push(Decode::decode(decoder)?);
486+
}
487+
Ok(vec)
488+
}
489+
490+
pub fn borrow_decode<
491+
'de,
492+
Context,
493+
D: BorrowDecoder<'de, Context = Context>,
494+
A: Array<Item = impl BorrowDecode<'de, Context>>,
495+
>(
496+
decoder: &mut D,
497+
) -> Result<SmallVec<A>, DecodeError> {
498+
let len = usize::decode(decoder)?;
499+
let mut vec = SmallVec::with_capacity(len);
500+
for _ in 0..len {
501+
vec.push(BorrowDecode::borrow_decode(decoder)?);
502+
}
503+
Ok(vec)
504+
}
505+
506+
#[cfg(test)]
507+
mod tests {
508+
use bincode::{decode_from_slice, encode_to_vec};
509+
510+
use super::*;
511+
512+
#[test]
513+
fn test_roundtrip() {
514+
let cfg = bincode::config::standard();
515+
516+
#[derive(Encode, Decode)]
517+
struct Wrapper(#[bincode(with = "crate::smallvec")] SmallVec<[u32; 4]>);
518+
519+
let vec1 = Wrapper(SmallVec::from_slice(&[1u32, 2, 3, 4, 5]));
520+
521+
let vec2: Wrapper = decode_from_slice(&encode_to_vec(&vec1, cfg).unwrap(), cfg)
522+
.unwrap()
523+
.0;
524+
525+
assert_eq!(vec1.0, vec2.0);
526+
}
527+
}
528+
}
529+
530+
pub mod owned_cow {
531+
//! Overrides the default [`BorrowDecode`] implementation to always use the owned representation
532+
//! of [`Cow`], so that the resulting [`BorrowDecode`] type is independent of the [`Cow`]'s
533+
//! lifetime.
534+
535+
use std::borrow::Cow;
536+
537+
use super::*;
538+
539+
#[allow(clippy::ptr_arg)]
540+
pub fn encode<E, T>(cow: &Cow<'_, T>, encoder: &mut E) -> Result<(), EncodeError>
541+
where
542+
E: Encoder,
543+
T: ToOwned + ?Sized,
544+
for<'a> &'a T: Encode,
545+
{
546+
cow.encode(encoder)
547+
}
548+
549+
pub fn decode<'cow, Context, D, T>(decoder: &mut D) -> Result<Cow<'cow, T>, DecodeError>
550+
where
551+
D: Decoder<Context = Context>,
552+
T: ToOwned + ?Sized,
553+
<T as ToOwned>::Owned: Decode<Context>,
554+
{
555+
Decode::decode(decoder)
556+
}
557+
558+
pub fn borrow_decode<'de, 'cow, Context, D, T>(
559+
decoder: &mut D,
560+
) -> Result<Cow<'cow, T>, DecodeError>
561+
where
562+
D: BorrowDecoder<'de, Context = Context>,
563+
T: ToOwned + ?Sized,
564+
<T as ToOwned>::Owned: Decode<Context>,
565+
{
566+
Decode::decode(decoder)
567+
}
568+
}

0 commit comments

Comments
 (0)