|
| 1 | +use ::smallvec::SmallVec; |
1 | 2 | use bincode::{ |
2 | 3 | BorrowDecode, Decode, Encode, |
3 | 4 | de::{BorrowDecoder, Decoder}, |
@@ -162,6 +163,83 @@ pub mod indexset { |
162 | 163 | } |
163 | 164 | } |
164 | 165 |
|
| 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 | + |
165 | 243 | pub mod mime_option { |
166 | 244 | use std::str::FromStr; |
167 | 245 |
|
@@ -381,3 +459,110 @@ pub mod either { |
381 | 459 | } |
382 | 460 | } |
383 | 461 | } |
| 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