|
| 1 | +use crate::{Decoder, Encoder}; |
| 2 | +use rkyv::de::deserializers::SharedDeserializeMap; |
| 3 | +use rkyv::ser::serializers::AllocSerializer; |
| 4 | +use rkyv::validation::validators::DefaultValidator; |
| 5 | +use rkyv::{Archive, CheckBytes, Deserialize, Fallible, Serialize}; |
| 6 | +use std::error::Error; |
| 7 | +use std::sync::Arc; |
| 8 | + |
| 9 | +/// A codec that relies on `rkyv` to encode data in the msgpack format. |
| 10 | +/// |
| 11 | +/// This is only available with the **`rkyv` feature** enabled. |
| 12 | +pub struct RkyvCodec; |
| 13 | + |
| 14 | +impl<T> Encoder<T> for RkyvCodec |
| 15 | +where |
| 16 | + T: Serialize<AllocSerializer<1024>>, |
| 17 | +{ |
| 18 | + type Error = <AllocSerializer<1024> as Fallible>::Error; |
| 19 | + type Encoded = Vec<u8>; |
| 20 | + |
| 21 | + fn encode(val: &T) -> Result<Self::Encoded, Self::Error> { |
| 22 | + Ok(rkyv::to_bytes::<T, 1024>(val)?.to_vec()) |
| 23 | + } |
| 24 | +} |
| 25 | + |
| 26 | +impl<T> Decoder<T> for RkyvCodec |
| 27 | +where |
| 28 | + T: Archive, |
| 29 | + for<'a> T::Archived: |
| 30 | + 'a + CheckBytes<DefaultValidator<'a>> + Deserialize<T, SharedDeserializeMap>, |
| 31 | +{ |
| 32 | + type Error = Arc<dyn Error>; |
| 33 | + type Encoded = [u8]; |
| 34 | + |
| 35 | + fn decode(val: &Self::Encoded) -> Result<T, Self::Error> { |
| 36 | + rkyv::from_bytes::<T>(val).map_err(|e| Arc::new(e) as Arc<dyn Error>) |
| 37 | + } |
| 38 | +} |
| 39 | + |
| 40 | +#[cfg(test)] |
| 41 | +mod tests { |
| 42 | + use super::*; |
| 43 | + |
| 44 | + #[test] |
| 45 | + fn test_rkyv_codec() { |
| 46 | + #[derive(Clone, Debug, PartialEq, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)] |
| 47 | + #[archive(check_bytes)] |
| 48 | + struct Test { |
| 49 | + s: String, |
| 50 | + i: i32, |
| 51 | + } |
| 52 | + let t = Test { |
| 53 | + s: String::from("party time 🎉"), |
| 54 | + i: 42, |
| 55 | + }; |
| 56 | + let enc = RkyvCodec::encode(&t).unwrap(); |
| 57 | + let dec: Test = RkyvCodec::decode(&enc).unwrap(); |
| 58 | + assert_eq!(dec, t); |
| 59 | + } |
| 60 | +} |
0 commit comments