├── .gitignore ├── README.md ├── benches ├── flavor │ └── mod.rs └── bincode.rs ├── src ├── lib.rs ├── error.rs ├── ser.rs └── de.rs ├── Cargo.toml ├── tests └── bincode.rs └── .github └── workflows └── ci.yml /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /Cargo.lock 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # serde-bench 2 | 3 | A minimal serialization format for use in benchmarks of core Serde. The format 4 | closely resembles Bincode. 5 | 6 |
7 | 8 | #### License 9 | 10 | 11 | Licensed under either of Apache License, Version 12 | 2.0 or MIT license at your option. 13 | 14 | 15 |
16 | 17 | 18 | Unless you explicitly state otherwise, any contribution intentionally submitted 19 | for inclusion in this crate by you, as defined in the Apache-2.0 license, shall 20 | be dual licensed as above, without any additional terms or conditions. 21 | 22 | -------------------------------------------------------------------------------- /benches/flavor/mod.rs: -------------------------------------------------------------------------------- 1 | use postcard::ser_flavors::Flavor; 2 | use postcard::Result; 3 | 4 | pub struct PreallocatedVec<'a> { 5 | vec: &'a mut Vec, 6 | } 7 | 8 | impl<'a> PreallocatedVec<'a> { 9 | pub fn new(vec: &'a mut Vec) -> Self { 10 | PreallocatedVec { vec } 11 | } 12 | } 13 | 14 | impl<'a> Flavor for PreallocatedVec<'a> { 15 | type Output = (); 16 | 17 | #[inline] 18 | fn try_extend(&mut self, data: &[u8]) -> Result<()> { 19 | self.vec.extend_from_slice(data); 20 | Ok(()) 21 | } 22 | 23 | #[inline] 24 | fn try_push(&mut self, data: u8) -> Result<()> { 25 | self.vec.push(data); 26 | Ok(()) 27 | } 28 | 29 | #[inline] 30 | fn finalize(self) -> Result { 31 | Ok(()) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow( 2 | clippy::cast_lossless, 3 | clippy::cast_possible_truncation, 4 | clippy::elidable_lifetime_names, 5 | clippy::missing_errors_doc, 6 | clippy::needless_lifetimes 7 | )] 8 | 9 | extern crate serde_core as serde; 10 | 11 | mod de; 12 | mod error; 13 | mod ser; 14 | 15 | use self::de::Deserializer; 16 | use self::ser::Serializer; 17 | use serde::{Deserialize, Serialize}; 18 | 19 | pub use self::error::{Error, Result}; 20 | 21 | pub fn serialize(out: &mut Vec, value: &T) -> Result<()> 22 | where 23 | T: Serialize, 24 | { 25 | let mut ser = Serializer::new(out); 26 | Serialize::serialize(value, &mut ser) 27 | } 28 | 29 | pub fn deserialize<'de, T>(bytes: &'de [u8]) -> Result 30 | where 31 | T: Deserialize<'de>, 32 | { 33 | let mut de = Deserializer::new(bytes); 34 | Deserialize::deserialize(&mut de) 35 | } 36 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "serde-bench" 3 | version = "0.0.14" 4 | authors = ["David Tolnay "] 5 | categories = ["encoding", "development-tools::profiling"] 6 | description = "Minimal serialization format for benchmarking Serde" 7 | documentation = "https://docs.rs/serde-bench/" 8 | edition = "2021" 9 | include = ["Cargo.toml", "src/**/*.rs"] 10 | keywords = ["serde", "serialization"] 11 | license = "MIT OR Apache-2.0" 12 | repository = "https://github.com/serde-rs/bench" 13 | rust-version = "1.68" 14 | 15 | [dependencies] 16 | byteorder = "1.4.3" 17 | serde_core = "1.0.220" 18 | 19 | [dev-dependencies] 20 | bincode = { version = "2", features = ["derive", "serde"] } 21 | postcard = { version = "1", features = ["use-std"] } 22 | serde = { version = "1", features = ["derive"] } 23 | 24 | [package.metadata.docs.rs] 25 | targets = ["x86_64-unknown-linux-gnu"] 26 | rustdoc-args = [ 27 | "--generate-link-to-definition", 28 | "--generate-macro-expansion", 29 | "--extern-html-root-url=core=https://doc.rust-lang.org", 30 | "--extern-html-root-url=alloc=https://doc.rust-lang.org", 31 | "--extern-html-root-url=std=https://doc.rust-lang.org", 32 | ] 33 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | use serde::{de, ser}; 2 | use std::fmt::{self, Display}; 3 | use std::{error, io, str, string}; 4 | 5 | #[derive(Debug)] 6 | pub struct Error { 7 | msg: String, 8 | } 9 | 10 | pub type Result = std::result::Result; 11 | 12 | impl Error { 13 | pub fn new(msg: T) -> Self { 14 | Error { 15 | msg: msg.to_string(), 16 | } 17 | } 18 | } 19 | 20 | impl error::Error for Error {} 21 | 22 | impl Display for Error { 23 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 24 | f.write_str(&self.msg) 25 | } 26 | } 27 | 28 | impl ser::Error for Error { 29 | fn custom(msg: T) -> Self { 30 | Error::new(msg) 31 | } 32 | } 33 | 34 | impl de::Error for Error { 35 | fn custom(msg: T) -> Self { 36 | Error::new(msg) 37 | } 38 | } 39 | 40 | impl From for Error { 41 | fn from(err: io::Error) -> Self { 42 | Error::new(err) 43 | } 44 | } 45 | 46 | impl From for Error { 47 | fn from(err: str::Utf8Error) -> Self { 48 | Error::new(err) 49 | } 50 | } 51 | 52 | impl From for Error { 53 | fn from(err: string::FromUtf8Error) -> Self { 54 | Error::new(err) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/bincode.rs: -------------------------------------------------------------------------------- 1 | #![allow( 2 | clippy::derive_partial_eq_without_eq, 3 | clippy::disallowed_names, 4 | clippy::unseparated_literal_suffix 5 | )] 6 | 7 | use serde::{Deserialize, Serialize}; 8 | 9 | #[derive(Serialize, Deserialize, PartialEq, Debug)] 10 | struct Foo { 11 | bar: String, 12 | baz: u64, 13 | derp: bool, 14 | } 15 | 16 | impl Default for Foo { 17 | fn default() -> Self { 18 | Foo { 19 | bar: "hello".into(), 20 | baz: 1337u64, 21 | derp: true, 22 | } 23 | } 24 | } 25 | 26 | #[test] 27 | fn test_ser() { 28 | let foo = Foo::default(); 29 | 30 | let bincode_bytes = bincode::serde::encode_to_vec(&foo, bincode::config::legacy()).unwrap(); 31 | 32 | let mut serde_bytes = Vec::new(); 33 | serde_bench::serialize(&mut serde_bytes, &foo).unwrap(); 34 | 35 | assert_eq!(bincode_bytes, serde_bytes); 36 | } 37 | 38 | #[test] 39 | fn test_de() { 40 | let foo = Foo::default(); 41 | let mut bytes = Vec::new(); 42 | serde_bench::serialize(&mut bytes, &foo).unwrap(); 43 | 44 | let bincode_foo = 45 | bincode::serde::decode_from_slice::(&bytes, bincode::config::legacy()) 46 | .unwrap() 47 | .0; 48 | assert_eq!(bincode_foo, foo); 49 | 50 | let serde_foo = serde_bench::deserialize::(&bytes).unwrap(); 51 | assert_eq!(serde_foo, foo); 52 | } 53 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | schedule: [cron: "40 1 * * *"] 8 | 9 | permissions: 10 | contents: read 11 | 12 | env: 13 | RUSTFLAGS: -Dwarnings 14 | 15 | jobs: 16 | test: 17 | name: Rust ${{matrix.rust}} 18 | runs-on: ubuntu-latest 19 | strategy: 20 | fail-fast: false 21 | matrix: 22 | rust: [nightly, beta, stable, 1.85.0, 1.68.0] 23 | timeout-minutes: 45 24 | steps: 25 | - uses: actions/checkout@v6 26 | - uses: dtolnay/rust-toolchain@master 27 | with: 28 | toolchain: ${{matrix.rust}} 29 | - run: cargo check 30 | - run: cargo test 31 | if: matrix.rust != '1.68.0' 32 | - run: cargo bench --no-run 33 | if: matrix.rust == 'nightly' 34 | - uses: actions/upload-artifact@v6 35 | if: matrix.rust == 'nightly' && always() 36 | with: 37 | name: Cargo.lock 38 | path: Cargo.lock 39 | continue-on-error: true 40 | 41 | minimal: 42 | name: Minimal versions 43 | runs-on: ubuntu-latest 44 | timeout-minutes: 45 45 | steps: 46 | - uses: actions/checkout@v6 47 | - uses: dtolnay/rust-toolchain@nightly 48 | - run: cargo generate-lockfile -Z minimal-versions 49 | - run: cargo check --locked 50 | 51 | doc: 52 | name: Documentation 53 | runs-on: ubuntu-latest 54 | timeout-minutes: 45 55 | env: 56 | RUSTDOCFLAGS: -Dwarnings 57 | steps: 58 | - uses: actions/checkout@v6 59 | - uses: dtolnay/rust-toolchain@nightly 60 | - uses: dtolnay/install@cargo-docs-rs 61 | - run: cargo docs-rs 62 | 63 | clippy: 64 | name: Clippy 65 | runs-on: ubuntu-latest 66 | timeout-minutes: 45 67 | steps: 68 | - uses: actions/checkout@v6 69 | - uses: dtolnay/rust-toolchain@clippy 70 | - run: cargo clippy --tests --benches -- -Dclippy::all -Dclippy::pedantic 71 | 72 | outdated: 73 | name: Outdated 74 | runs-on: ubuntu-latest 75 | if: github.event_name != 'pull_request' 76 | timeout-minutes: 45 77 | steps: 78 | - uses: actions/checkout@v6 79 | - uses: dtolnay/rust-toolchain@stable 80 | - uses: dtolnay/install@cargo-outdated 81 | - run: cargo outdated --workspace --ignore embedded-io --ignore bincode --exit-code 1 82 | -------------------------------------------------------------------------------- /benches/bincode.rs: -------------------------------------------------------------------------------- 1 | #![feature(test)] 2 | #![allow(clippy::elidable_lifetime_names)] 3 | 4 | extern crate test; 5 | 6 | mod flavor; 7 | 8 | use crate::flavor::PreallocatedVec; 9 | use serde::{Deserialize, Serialize}; 10 | use std::hint::black_box; 11 | use test::Bencher; 12 | 13 | #[derive(Serialize, Deserialize, bincode::Encode, bincode::Decode)] 14 | struct Foo { 15 | bar: String, 16 | baz: u64, 17 | derp: bool, 18 | } 19 | 20 | impl Default for Foo { 21 | fn default() -> Self { 22 | Foo { 23 | bar: "hello".into(), 24 | baz: 1337u64, 25 | derp: true, 26 | } 27 | } 28 | } 29 | 30 | #[bench] 31 | fn bincode_serde_deserialize(b: &mut Bencher) { 32 | let foo = Foo::default(); 33 | let bytes = bincode::serde::encode_to_vec(&foo, bincode::config::standard()).unwrap(); 34 | 35 | b.iter(|| { 36 | let bytes = black_box(&bytes); 37 | bincode::serde::decode_from_slice::(bytes, bincode::config::standard()).unwrap() 38 | }); 39 | } 40 | 41 | #[bench] 42 | fn bincode_serde_serialize(b: &mut Bencher) { 43 | let foo = Foo::default(); 44 | let mut bytes = Vec::with_capacity(128); 45 | 46 | b.iter(|| { 47 | let foo = black_box(&foo); 48 | bytes.clear(); 49 | bincode::serde::encode_into_std_write(foo, &mut bytes, bincode::config::standard()) 50 | .unwrap(); 51 | }); 52 | } 53 | 54 | #[bench] 55 | fn bincode_decode(b: &mut Bencher) { 56 | let foo = Foo::default(); 57 | let bytes = bincode::encode_to_vec(&foo, bincode::config::standard()).unwrap(); 58 | 59 | b.iter(|| { 60 | let bytes = black_box(&bytes); 61 | bincode::decode_from_slice::(bytes, bincode::config::standard()).unwrap() 62 | }); 63 | } 64 | 65 | #[bench] 66 | fn bincode_encode(b: &mut Bencher) { 67 | let foo = Foo::default(); 68 | let mut bytes = Vec::with_capacity(128); 69 | 70 | b.iter(|| { 71 | let foo = black_box(&foo); 72 | bytes.clear(); 73 | bincode::encode_into_std_write(foo, &mut bytes, bincode::config::standard()).unwrap(); 74 | }); 75 | } 76 | 77 | #[bench] 78 | fn postcard_deserialize(b: &mut Bencher) { 79 | let foo = Foo::default(); 80 | let bytes = postcard::to_stdvec(&foo).unwrap(); 81 | 82 | b.iter(|| { 83 | let bytes = black_box(&bytes); 84 | postcard::from_bytes::(bytes).unwrap() 85 | }); 86 | } 87 | 88 | #[bench] 89 | fn postcard_serialize(b: &mut Bencher) { 90 | let foo = Foo::default(); 91 | let mut bytes = Vec::with_capacity(128); 92 | 93 | b.iter(|| { 94 | let foo = black_box(&foo); 95 | bytes.clear(); 96 | postcard::serialize_with_flavor(foo, PreallocatedVec::new(&mut bytes)).unwrap(); 97 | }); 98 | } 99 | 100 | #[bench] 101 | fn serde_deserialize(b: &mut Bencher) { 102 | let foo = Foo::default(); 103 | let mut bytes = Vec::new(); 104 | serde_bench::serialize(&mut bytes, &foo).unwrap(); 105 | 106 | b.iter(|| { 107 | let bytes = black_box(&bytes); 108 | serde_bench::deserialize::(bytes).unwrap() 109 | }); 110 | } 111 | 112 | #[bench] 113 | fn serde_serialize(b: &mut Bencher) { 114 | let foo = Foo::default(); 115 | let mut bytes = Vec::with_capacity(128); 116 | 117 | b.iter(|| { 118 | let foo = black_box(&foo); 119 | bytes.clear(); 120 | serde_bench::serialize(&mut bytes, foo).unwrap(); 121 | }); 122 | } 123 | -------------------------------------------------------------------------------- /src/ser.rs: -------------------------------------------------------------------------------- 1 | use crate::{Error, Result}; 2 | use byteorder::{NativeEndian, WriteBytesExt}; 3 | use serde::ser::{ 4 | SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple, 5 | SerializeTupleStruct, SerializeTupleVariant, 6 | }; 7 | use std::io::Write; 8 | 9 | pub struct Serializer { 10 | writer: W, 11 | } 12 | 13 | impl Serializer 14 | where 15 | W: Write, 16 | { 17 | pub fn new(w: W) -> Self { 18 | Serializer { writer: w } 19 | } 20 | } 21 | 22 | impl serde::Serializer for &mut Serializer 23 | where 24 | W: Write, 25 | { 26 | type Ok = (); 27 | type Error = Error; 28 | 29 | type SerializeSeq = Self; 30 | type SerializeTuple = Self; 31 | type SerializeTupleStruct = Self; 32 | type SerializeTupleVariant = Self; 33 | type SerializeMap = Self; 34 | type SerializeStruct = Self; 35 | type SerializeStructVariant = Self; 36 | 37 | #[inline] 38 | fn serialize_unit(self) -> Result<()> { 39 | Ok(()) 40 | } 41 | 42 | #[inline] 43 | fn serialize_unit_struct(self, _: &'static str) -> Result<()> { 44 | Ok(()) 45 | } 46 | 47 | #[inline] 48 | fn serialize_bool(self, v: bool) -> Result<()> { 49 | self.writer.write_u8(v as u8).map_err(From::from) 50 | } 51 | 52 | #[inline] 53 | fn serialize_u8(self, v: u8) -> Result<()> { 54 | self.writer.write_u8(v).map_err(From::from) 55 | } 56 | 57 | #[inline] 58 | fn serialize_u16(self, v: u16) -> Result<()> { 59 | self.writer.write_u16::(v).map_err(From::from) 60 | } 61 | 62 | #[inline] 63 | fn serialize_u32(self, v: u32) -> Result<()> { 64 | self.writer.write_u32::(v).map_err(From::from) 65 | } 66 | 67 | #[inline] 68 | fn serialize_u64(self, v: u64) -> Result<()> { 69 | self.writer.write_u64::(v).map_err(From::from) 70 | } 71 | 72 | #[inline] 73 | fn serialize_u128(self, v: u128) -> Result<()> { 74 | self.writer 75 | .write_u128::(v) 76 | .map_err(From::from) 77 | } 78 | 79 | #[inline] 80 | fn serialize_i8(self, v: i8) -> Result<()> { 81 | self.writer.write_i8(v).map_err(From::from) 82 | } 83 | 84 | #[inline] 85 | fn serialize_i16(self, v: i16) -> Result<()> { 86 | self.writer.write_i16::(v).map_err(From::from) 87 | } 88 | 89 | #[inline] 90 | fn serialize_i32(self, v: i32) -> Result<()> { 91 | self.writer.write_i32::(v).map_err(From::from) 92 | } 93 | 94 | #[inline] 95 | fn serialize_i64(self, v: i64) -> Result<()> { 96 | self.writer.write_i64::(v).map_err(From::from) 97 | } 98 | 99 | #[inline] 100 | fn serialize_i128(self, v: i128) -> Result<()> { 101 | self.writer 102 | .write_i128::(v) 103 | .map_err(From::from) 104 | } 105 | 106 | #[inline] 107 | fn serialize_f32(self, v: f32) -> Result<()> { 108 | self.writer.write_f32::(v).map_err(From::from) 109 | } 110 | 111 | #[inline] 112 | fn serialize_f64(self, v: f64) -> Result<()> { 113 | self.writer.write_f64::(v).map_err(From::from) 114 | } 115 | 116 | #[inline] 117 | fn serialize_str(self, v: &str) -> Result<()> { 118 | self.serialize_u64(v.len() as u64)?; 119 | self.writer.write_all(v.as_bytes()).map_err(From::from) 120 | } 121 | 122 | #[inline] 123 | fn serialize_char(self, c: char) -> Result<()> { 124 | self.writer 125 | .write_all(encode_utf8(c).as_slice()) 126 | .map_err(From::from) 127 | } 128 | 129 | #[inline] 130 | fn serialize_bytes(self, v: &[u8]) -> Result<()> { 131 | self.serialize_u64(v.len() as u64)?; 132 | self.writer.write_all(v).map_err(From::from) 133 | } 134 | 135 | #[inline] 136 | fn serialize_none(self) -> Result<()> { 137 | self.writer.write_u8(0).map_err(From::from) 138 | } 139 | 140 | #[inline] 141 | fn serialize_some(self, v: &T) -> Result<()> 142 | where 143 | T: ?Sized + serde::Serialize, 144 | { 145 | self.writer.write_u8(1)?; 146 | v.serialize(self) 147 | } 148 | 149 | #[inline] 150 | fn serialize_seq(self, len: Option) -> Result { 151 | let len = len.expect("do not know how to serialize a sequence with no length"); 152 | self.serialize_u64(len as u64)?; 153 | Ok(self) 154 | } 155 | 156 | #[inline] 157 | fn serialize_tuple(self, _len: usize) -> Result { 158 | Ok(self) 159 | } 160 | 161 | #[inline] 162 | fn serialize_tuple_struct( 163 | self, 164 | _name: &'static str, 165 | _len: usize, 166 | ) -> Result { 167 | Ok(self) 168 | } 169 | 170 | #[inline] 171 | fn serialize_tuple_variant( 172 | self, 173 | _name: &'static str, 174 | variant_index: u32, 175 | _variant: &'static str, 176 | _len: usize, 177 | ) -> Result { 178 | self.serialize_u32(variant_index)?; 179 | Ok(self) 180 | } 181 | 182 | #[inline] 183 | fn serialize_map(self, len: Option) -> Result { 184 | let len = len.expect("do not know how to serialize a map with no length"); 185 | self.serialize_u64(len as u64)?; 186 | Ok(self) 187 | } 188 | 189 | #[inline] 190 | fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { 191 | Ok(self) 192 | } 193 | 194 | #[inline] 195 | fn serialize_struct_variant( 196 | self, 197 | _name: &'static str, 198 | variant_index: u32, 199 | _variant: &'static str, 200 | _len: usize, 201 | ) -> Result { 202 | self.serialize_u32(variant_index)?; 203 | Ok(self) 204 | } 205 | 206 | #[inline] 207 | fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result<()> 208 | where 209 | T: ?Sized + serde::ser::Serialize, 210 | { 211 | value.serialize(self) 212 | } 213 | 214 | #[inline] 215 | fn serialize_newtype_variant( 216 | self, 217 | _name: &'static str, 218 | variant_index: u32, 219 | _variant: &'static str, 220 | value: &T, 221 | ) -> Result<()> 222 | where 223 | T: ?Sized + serde::ser::Serialize, 224 | { 225 | self.serialize_u32(variant_index)?; 226 | value.serialize(self) 227 | } 228 | 229 | #[inline] 230 | fn serialize_unit_variant( 231 | self, 232 | _name: &'static str, 233 | variant_index: u32, 234 | _variant: &'static str, 235 | ) -> Result<()> { 236 | self.serialize_u32(variant_index) 237 | } 238 | 239 | fn is_human_readable(&self) -> bool { 240 | false 241 | } 242 | } 243 | 244 | impl SerializeSeq for &mut Serializer 245 | where 246 | W: Write, 247 | { 248 | type Ok = (); 249 | type Error = Error; 250 | 251 | #[inline] 252 | fn serialize_element(&mut self, value: &V) -> Result<()> 253 | where 254 | V: ?Sized + serde::Serialize, 255 | { 256 | value.serialize(&mut **self) 257 | } 258 | 259 | #[inline] 260 | fn end(self) -> Result<()> { 261 | Ok(()) 262 | } 263 | } 264 | 265 | impl SerializeTuple for &mut Serializer 266 | where 267 | W: Write, 268 | { 269 | type Ok = (); 270 | type Error = Error; 271 | 272 | #[inline] 273 | fn serialize_element(&mut self, value: &V) -> Result<()> 274 | where 275 | V: ?Sized + serde::Serialize, 276 | { 277 | value.serialize(&mut **self) 278 | } 279 | 280 | #[inline] 281 | fn end(self) -> Result<()> { 282 | Ok(()) 283 | } 284 | } 285 | 286 | impl SerializeTupleStruct for &mut Serializer 287 | where 288 | W: Write, 289 | { 290 | type Ok = (); 291 | type Error = Error; 292 | 293 | #[inline] 294 | fn serialize_field(&mut self, value: &V) -> Result<()> 295 | where 296 | V: ?Sized + serde::Serialize, 297 | { 298 | value.serialize(&mut **self) 299 | } 300 | 301 | #[inline] 302 | fn end(self) -> Result<()> { 303 | Ok(()) 304 | } 305 | } 306 | 307 | impl SerializeTupleVariant for &mut Serializer 308 | where 309 | W: Write, 310 | { 311 | type Ok = (); 312 | type Error = Error; 313 | 314 | #[inline] 315 | fn serialize_field(&mut self, value: &V) -> Result<()> 316 | where 317 | V: ?Sized + serde::Serialize, 318 | { 319 | value.serialize(&mut **self) 320 | } 321 | 322 | #[inline] 323 | fn end(self) -> Result<()> { 324 | Ok(()) 325 | } 326 | } 327 | 328 | impl SerializeMap for &mut Serializer 329 | where 330 | W: Write, 331 | { 332 | type Ok = (); 333 | type Error = Error; 334 | 335 | #[inline] 336 | fn serialize_key(&mut self, key: &K) -> Result<()> 337 | where 338 | K: ?Sized + serde::Serialize, 339 | { 340 | key.serialize(&mut **self) 341 | } 342 | 343 | #[inline] 344 | fn serialize_value(&mut self, value: &V) -> Result<()> 345 | where 346 | V: ?Sized + serde::Serialize, 347 | { 348 | value.serialize(&mut **self) 349 | } 350 | 351 | #[inline] 352 | fn end(self) -> Result<()> { 353 | Ok(()) 354 | } 355 | } 356 | 357 | impl SerializeStruct for &mut Serializer 358 | where 359 | W: Write, 360 | { 361 | type Ok = (); 362 | type Error = Error; 363 | 364 | #[inline] 365 | fn serialize_field(&mut self, _key: &'static str, value: &V) -> Result<()> 366 | where 367 | V: ?Sized + serde::Serialize, 368 | { 369 | value.serialize(&mut **self) 370 | } 371 | 372 | #[inline] 373 | fn end(self) -> Result<()> { 374 | Ok(()) 375 | } 376 | } 377 | 378 | impl SerializeStructVariant for &mut Serializer 379 | where 380 | W: Write, 381 | { 382 | type Ok = (); 383 | type Error = Error; 384 | 385 | #[inline] 386 | fn serialize_field(&mut self, _key: &'static str, value: &V) -> Result<()> 387 | where 388 | V: ?Sized + serde::Serialize, 389 | { 390 | value.serialize(&mut **self) 391 | } 392 | 393 | #[inline] 394 | fn end(self) -> Result<()> { 395 | Ok(()) 396 | } 397 | } 398 | 399 | #[inline] 400 | fn encode_utf8(c: char) -> EncodeUtf8 { 401 | const TAG_CONT: u8 = 0b1000_0000; 402 | const TAG_TWO_B: u8 = 0b1100_0000; 403 | const TAG_THREE_B: u8 = 0b1110_0000; 404 | const TAG_FOUR_B: u8 = 0b1111_0000; 405 | const MAX_ONE_B: u32 = 0x80; 406 | const MAX_TWO_B: u32 = 0x800; 407 | const MAX_THREE_B: u32 = 0x10000; 408 | 409 | let code = c as u32; 410 | let mut buf = [0; 4]; 411 | let pos = if code < MAX_ONE_B { 412 | buf[3] = code as u8; 413 | 3 414 | } else if code < MAX_TWO_B { 415 | buf[2] = ((code >> 6) & 0x1F) as u8 | TAG_TWO_B; 416 | buf[3] = (code & 0x3F) as u8 | TAG_CONT; 417 | 2 418 | } else if code < MAX_THREE_B { 419 | buf[1] = ((code >> 12) & 0x0F) as u8 | TAG_THREE_B; 420 | buf[2] = ((code >> 6) & 0x3F) as u8 | TAG_CONT; 421 | buf[3] = (code & 0x3F) as u8 | TAG_CONT; 422 | 1 423 | } else { 424 | buf[0] = ((code >> 18) & 0x07) as u8 | TAG_FOUR_B; 425 | buf[1] = ((code >> 12) & 0x3F) as u8 | TAG_CONT; 426 | buf[2] = ((code >> 6) & 0x3F) as u8 | TAG_CONT; 427 | buf[3] = (code & 0x3F) as u8 | TAG_CONT; 428 | 0 429 | }; 430 | EncodeUtf8 { buf, pos } 431 | } 432 | 433 | struct EncodeUtf8 { 434 | buf: [u8; 4], 435 | pos: usize, 436 | } 437 | 438 | impl EncodeUtf8 { 439 | #[inline] 440 | fn as_slice(&self) -> &[u8] { 441 | &self.buf[self.pos..] 442 | } 443 | } 444 | -------------------------------------------------------------------------------- /src/de.rs: -------------------------------------------------------------------------------- 1 | use crate::{Error, Result}; 2 | use byteorder::{NativeEndian, ReadBytesExt}; 3 | use serde::de::{ 4 | self, Deserialize, DeserializeSeed, EnumAccess, IntoDeserializer, SeqAccess, VariantAccess, 5 | Visitor, 6 | }; 7 | use std::str; 8 | 9 | pub struct Deserializer<'de> { 10 | bytes: &'de [u8], 11 | } 12 | 13 | impl<'de> Deserializer<'de> { 14 | pub fn new(bytes: &'de [u8]) -> Self { 15 | Deserializer { bytes } 16 | } 17 | 18 | #[inline] 19 | fn read_slice(&mut self) -> Result<&'de [u8]> { 20 | let len = Deserialize::deserialize(&mut *self)?; 21 | let (slice, rest) = self.bytes.split_at(len); 22 | self.bytes = rest; 23 | Ok(slice) 24 | } 25 | 26 | #[inline] 27 | fn read_str(&mut self) -> Result<&'de str> { 28 | str::from_utf8(self.read_slice()?).map_err(Into::into) 29 | } 30 | } 31 | 32 | macro_rules! impl_nums { 33 | ($dser_method:ident, $visitor_method:ident, $reader_method:ident) => { 34 | #[inline] 35 | fn $dser_method(self, visitor: V) -> Result 36 | where 37 | V: Visitor<'de>, 38 | { 39 | let value = self.bytes.$reader_method::()?; 40 | visitor.$visitor_method(value) 41 | } 42 | }; 43 | } 44 | 45 | impl<'de> serde::Deserializer<'de> for &mut Deserializer<'de> { 46 | type Error = Error; 47 | 48 | fn deserialize_any(self, _visitor: V) -> Result 49 | where 50 | V: Visitor<'de>, 51 | { 52 | Err(Error::new("`deserialize_any` is not supported")) 53 | } 54 | 55 | #[inline] 56 | fn deserialize_bool(self, visitor: V) -> Result 57 | where 58 | V: Visitor<'de>, 59 | { 60 | match self.bytes.read_u8()? { 61 | 1 => visitor.visit_bool(true), 62 | 0 => visitor.visit_bool(false), 63 | _ => Err(Error::new("invalid boolean")), 64 | } 65 | } 66 | 67 | impl_nums!(deserialize_u16, visit_u16, read_u16); 68 | impl_nums!(deserialize_u32, visit_u32, read_u32); 69 | impl_nums!(deserialize_u64, visit_u64, read_u64); 70 | impl_nums!(deserialize_u128, visit_u128, read_u128); 71 | impl_nums!(deserialize_i16, visit_i16, read_i16); 72 | impl_nums!(deserialize_i32, visit_i32, read_i32); 73 | impl_nums!(deserialize_i64, visit_i64, read_i64); 74 | impl_nums!(deserialize_i128, visit_i128, read_i128); 75 | impl_nums!(deserialize_f32, visit_f32, read_f32); 76 | impl_nums!(deserialize_f64, visit_f64, read_f64); 77 | 78 | #[inline] 79 | fn deserialize_u8(self, visitor: V) -> Result 80 | where 81 | V: Visitor<'de>, 82 | { 83 | visitor.visit_u8(self.bytes.read_u8()?) 84 | } 85 | 86 | #[inline] 87 | fn deserialize_i8(self, visitor: V) -> Result 88 | where 89 | V: Visitor<'de>, 90 | { 91 | visitor.visit_i8(self.bytes.read_i8()?) 92 | } 93 | 94 | #[inline] 95 | fn deserialize_unit(self, visitor: V) -> Result 96 | where 97 | V: Visitor<'de>, 98 | { 99 | visitor.visit_unit() 100 | } 101 | 102 | #[inline] 103 | fn deserialize_char(self, visitor: V) -> Result 104 | where 105 | V: Visitor<'de>, 106 | { 107 | let width = utf8_char_width(self.bytes[0]); 108 | if width == 1 { 109 | return visitor.visit_char(self.bytes[0] as char); 110 | } 111 | if width == 0 { 112 | return Err(Error::new("invalid char")); 113 | } 114 | let res = match str::from_utf8(&self.bytes[..width]) { 115 | Ok(s) => s.chars().next().unwrap(), 116 | Err(err) => { 117 | return Err(err.into()); 118 | } 119 | }; 120 | self.bytes = &self.bytes[width..]; 121 | visitor.visit_char(res) 122 | } 123 | 124 | #[inline] 125 | fn deserialize_str(self, visitor: V) -> Result 126 | where 127 | V: Visitor<'de>, 128 | { 129 | visitor.visit_borrowed_str(self.read_str()?) 130 | } 131 | 132 | #[inline] 133 | fn deserialize_string(self, visitor: V) -> Result 134 | where 135 | V: Visitor<'de>, 136 | { 137 | visitor.visit_borrowed_str(self.read_str()?) 138 | } 139 | 140 | #[inline] 141 | fn deserialize_bytes(self, visitor: V) -> Result 142 | where 143 | V: Visitor<'de>, 144 | { 145 | visitor.visit_borrowed_bytes(self.read_slice()?) 146 | } 147 | 148 | #[inline] 149 | fn deserialize_byte_buf(self, visitor: V) -> Result 150 | where 151 | V: Visitor<'de>, 152 | { 153 | visitor.visit_borrowed_bytes(self.read_slice()?) 154 | } 155 | 156 | #[inline] 157 | fn deserialize_enum( 158 | self, 159 | _enum: &'static str, 160 | _variants: &'static [&'static str], 161 | visitor: V, 162 | ) -> Result 163 | where 164 | V: Visitor<'de>, 165 | { 166 | visitor.visit_enum(self) 167 | } 168 | 169 | #[inline] 170 | fn deserialize_tuple(self, _len: usize, visitor: V) -> Result 171 | where 172 | V: Visitor<'de>, 173 | { 174 | visitor.visit_seq(self) 175 | } 176 | 177 | #[inline] 178 | fn deserialize_option(self, visitor: V) -> Result 179 | where 180 | V: Visitor<'de>, 181 | { 182 | match self.bytes.read_u8()? { 183 | 0 => visitor.visit_none(), 184 | 1 => visitor.visit_some(self), 185 | _ => Err(Error::new("invalid Option")), 186 | } 187 | } 188 | 189 | #[inline] 190 | fn deserialize_seq(self, visitor: V) -> Result 191 | where 192 | V: Visitor<'de>, 193 | { 194 | struct SeqAccess<'a, 'de: 'a> { 195 | deserializer: &'a mut Deserializer<'de>, 196 | remaining: usize, 197 | } 198 | 199 | impl<'de, 'a> de::SeqAccess<'de> for SeqAccess<'a, 'de> { 200 | type Error = Error; 201 | 202 | #[inline] 203 | fn next_element_seed(&mut self, seed: T) -> Result> 204 | where 205 | T: DeserializeSeed<'de>, 206 | { 207 | if self.remaining > 0 { 208 | self.remaining -= 1; 209 | seed.deserialize(&mut *self.deserializer).map(Some) 210 | } else { 211 | Ok(None) 212 | } 213 | } 214 | } 215 | 216 | let len = Deserialize::deserialize(&mut *self)?; 217 | 218 | visitor.visit_seq(SeqAccess { 219 | deserializer: self, 220 | remaining: len, 221 | }) 222 | } 223 | 224 | #[inline] 225 | fn deserialize_map(self, visitor: V) -> Result 226 | where 227 | V: Visitor<'de>, 228 | { 229 | struct MapAccess<'a, 'de: 'a> { 230 | deserializer: &'a mut Deserializer<'de>, 231 | remaining: usize, 232 | } 233 | 234 | impl<'de, 'a> de::MapAccess<'de> for MapAccess<'a, 'de> { 235 | type Error = Error; 236 | 237 | #[inline] 238 | fn next_key_seed(&mut self, seed: K) -> Result> 239 | where 240 | K: DeserializeSeed<'de>, 241 | { 242 | if self.remaining > 0 { 243 | self.remaining -= 1; 244 | seed.deserialize(&mut *self.deserializer).map(Some) 245 | } else { 246 | Ok(None) 247 | } 248 | } 249 | 250 | #[inline] 251 | fn next_value_seed(&mut self, seed: V) -> Result 252 | where 253 | V: DeserializeSeed<'de>, 254 | { 255 | seed.deserialize(&mut *self.deserializer) 256 | } 257 | } 258 | 259 | let len = Deserialize::deserialize(&mut *self)?; 260 | 261 | visitor.visit_map(MapAccess { 262 | deserializer: self, 263 | remaining: len, 264 | }) 265 | } 266 | 267 | #[inline] 268 | fn deserialize_struct( 269 | self, 270 | _name: &str, 271 | _fields: &'static [&'static str], 272 | visitor: V, 273 | ) -> Result 274 | where 275 | V: Visitor<'de>, 276 | { 277 | visitor.visit_seq(self) 278 | } 279 | 280 | fn deserialize_identifier(self, _visitor: V) -> Result 281 | where 282 | V: Visitor<'de>, 283 | { 284 | Err(Error::new("`deserialize_identifier` is not supported")) 285 | } 286 | 287 | #[inline] 288 | fn deserialize_newtype_struct(self, _name: &str, visitor: V) -> Result 289 | where 290 | V: Visitor<'de>, 291 | { 292 | visitor.visit_newtype_struct(self) 293 | } 294 | 295 | #[inline] 296 | fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result 297 | where 298 | V: Visitor<'de>, 299 | { 300 | visitor.visit_unit() 301 | } 302 | 303 | #[inline] 304 | fn deserialize_tuple_struct( 305 | self, 306 | _name: &'static str, 307 | _len: usize, 308 | visitor: V, 309 | ) -> Result 310 | where 311 | V: Visitor<'de>, 312 | { 313 | visitor.visit_seq(self) 314 | } 315 | 316 | fn deserialize_ignored_any(self, _visitor: V) -> Result 317 | where 318 | V: Visitor<'de>, 319 | { 320 | Err(Error::new("`deserialize_ignored_any` is not supported")) 321 | } 322 | 323 | fn is_human_readable(&self) -> bool { 324 | false 325 | } 326 | } 327 | 328 | // For tuples, structs, tuple structs, and fixed size seqs. 329 | impl<'de> SeqAccess<'de> for Deserializer<'de> { 330 | type Error = Error; 331 | 332 | #[inline] 333 | fn next_element_seed(&mut self, seed: T) -> Result> 334 | where 335 | T: DeserializeSeed<'de>, 336 | { 337 | seed.deserialize(self).map(Some) 338 | } 339 | } 340 | 341 | impl<'de> EnumAccess<'de> for &mut Deserializer<'de> { 342 | type Error = Error; 343 | type Variant = Self; 344 | 345 | #[inline] 346 | fn variant_seed(self, seed: V) -> Result<(V::Value, Self)> 347 | where 348 | V: DeserializeSeed<'de>, 349 | { 350 | let index = Deserialize::deserialize(&mut *self)?; 351 | let deserializer = >::into_deserializer(index); 352 | let value = seed.deserialize(deserializer)?; 353 | Ok((value, self)) 354 | } 355 | } 356 | 357 | impl<'de> VariantAccess<'de> for &mut Deserializer<'de> { 358 | type Error = Error; 359 | 360 | #[inline] 361 | fn unit_variant(self) -> Result<()> { 362 | Ok(()) 363 | } 364 | 365 | #[inline] 366 | fn newtype_variant_seed(self, seed: T) -> Result 367 | where 368 | T: DeserializeSeed<'de>, 369 | { 370 | seed.deserialize(self) 371 | } 372 | 373 | #[inline] 374 | fn tuple_variant(self, _len: usize, visitor: V) -> Result 375 | where 376 | V: Visitor<'de>, 377 | { 378 | visitor.visit_seq(self) 379 | } 380 | 381 | #[inline] 382 | fn struct_variant(self, _fields: &'static [&'static str], visitor: V) -> Result 383 | where 384 | V: Visitor<'de>, 385 | { 386 | visitor.visit_seq(self) 387 | } 388 | } 389 | 390 | #[rustfmt::skip] 391 | static UTF8_CHAR_WIDTH: [u8; 256] = [ 392 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 393 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x1F 394 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 395 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x3F 396 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 397 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x5F 398 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 399 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x7F 400 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 401 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x9F 402 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 403 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xBF 404 | 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 405 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xDF 406 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xEF 407 | 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xFF 408 | ]; 409 | 410 | #[inline] 411 | fn utf8_char_width(b: u8) -> usize { 412 | UTF8_CHAR_WIDTH[b as usize] as usize 413 | } 414 | --------------------------------------------------------------------------------