diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml new file mode 100644 index 0000000..c301947 --- /dev/null +++ b/.github/workflows/CI.yml @@ -0,0 +1,24 @@ +on: + push: + branches: [master] + pull_request: + +name: Continuous integration + +jobs: + + fmt: + name: format + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + override: true + profile: minimal + components: rustfmt + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: -- --check diff --git a/benches/bench.rs b/benches/bench.rs index 7b09708..4042b9a 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -2,82 +2,88 @@ extern crate test; -use std::io::Write; +use speedy::{Context, Endianness, Readable, Reader, Writable}; use std::borrow::Cow; -use test::{Bencher, black_box}; -use speedy::{Context, Readable, Reader, Writable, Endianness}; +use std::io::Write; +use test::{black_box, Bencher}; #[bench] -fn write_manual_megabyte_buffer( b: &mut Bencher ) { - let mut buffer: Vec< u8 > = Vec::new(); - buffer.resize( 1024 * 1024, 1 ); - buffer = black_box( buffer ); - b.iter( || { +fn write_manual_megabyte_buffer(b: &mut Bencher) { + let mut buffer: Vec = Vec::new(); + buffer.resize(1024 * 1024, 1); + buffer = black_box(buffer); + b.iter(|| { let mut output = Vec::new(); - Write::write_all( &mut output, &buffer ).unwrap(); + Write::write_all(&mut output, &buffer).unwrap(); output }) } // These two benchmarks should have exactly the same speeds. #[bench] -fn write_speedy_megabyte_buffer_le( b: &mut Bencher ) { - let mut buffer: Vec< u8 > = Vec::new(); - buffer.resize( 1024 * 1024, 1 ); - buffer = black_box( buffer ); - b.iter( || { +fn write_speedy_megabyte_buffer_le(b: &mut Bencher) { + let mut buffer: Vec = Vec::new(); + buffer.resize(1024 * 1024, 1); + buffer = black_box(buffer); + b.iter(|| { let mut output = Vec::new(); - buffer.write_to_stream_with_ctx( Endianness::LittleEndian, &mut output ).unwrap(); + buffer + .write_to_stream_with_ctx(Endianness::LittleEndian, &mut output) + .unwrap(); output }) } #[bench] -fn write_speedy_megabyte_buffer_be( b: &mut Bencher ) { - let mut buffer: Vec< u8 > = Vec::new(); - buffer.resize( 1024 * 1024, 1 ); - buffer = black_box( buffer ); - b.iter( || { +fn write_speedy_megabyte_buffer_be(b: &mut Bencher) { + let mut buffer: Vec = Vec::new(); + buffer.resize(1024 * 1024, 1); + buffer = black_box(buffer); + b.iter(|| { let mut output = Vec::new(); - buffer.write_to_stream_with_ctx( Endianness::BigEndian, &mut output ).unwrap(); + buffer + .write_to_stream_with_ctx(Endianness::BigEndian, &mut output) + .unwrap(); output }) } #[bench] -fn read_speedy_megabyte_buffer_cow_borrowed( b: &mut Bencher ) { - let mut buffer: Vec< u8 > = Vec::new(); - buffer.resize( 1024 * 1024, 1 ); - let mut buffer = buffer.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap(); - - buffer = black_box( buffer ); - b.iter( || { - let deserialized: Cow< [u8] > = Readable::read_from_buffer_with_ctx( Endianness::NATIVE, &buffer ).unwrap(); +fn read_speedy_megabyte_buffer_cow_borrowed(b: &mut Bencher) { + let mut buffer: Vec = Vec::new(); + buffer.resize(1024 * 1024, 1); + let mut buffer = buffer.write_to_vec_with_ctx(Endianness::NATIVE).unwrap(); + + buffer = black_box(buffer); + b.iter(|| { + let deserialized: Cow<[u8]> = + Readable::read_from_buffer_with_ctx(Endianness::NATIVE, &buffer).unwrap(); deserialized }) } #[bench] -fn read_speedy_megabyte_buffer_cow_owned( b: &mut Bencher ) { - let mut buffer: Vec< u8 > = Vec::new(); - buffer.resize( 1024 * 1024, 1 ); - let mut buffer = buffer.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap(); - - buffer = black_box( buffer ); - b.iter( || { - let deserialized: Cow< [u8] > = Readable::read_from_buffer_copying_data_with_ctx( Endianness::NATIVE, &buffer ).unwrap(); +fn read_speedy_megabyte_buffer_cow_owned(b: &mut Bencher) { + let mut buffer: Vec = Vec::new(); + buffer.resize(1024 * 1024, 1); + let mut buffer = buffer.write_to_vec_with_ctx(Endianness::NATIVE).unwrap(); + + buffer = black_box(buffer); + b.iter(|| { + let deserialized: Cow<[u8]> = + Readable::read_from_buffer_copying_data_with_ctx(Endianness::NATIVE, &buffer).unwrap(); deserialized }) } #[repr(transparent)] #[derive(Copy, Clone, Writable)] -struct Byte( u8 ); +struct Byte(u8); -impl< 'a, C: Context > Readable< 'a, C > for Byte { +impl<'a, C: Context> Readable<'a, C> for Byte { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - Ok( Byte( reader.read_u8()? ) ) + fn read_from>(reader: &mut R) -> Result { + Ok(Byte(reader.read_u8()?)) } #[inline] @@ -87,14 +93,15 @@ impl< 'a, C: Context > Readable< 'a, C > for Byte { } #[bench] -fn read_speedy_megabyte_buffer_vec_non_primitive( b: &mut Bencher ) { - let mut buffer: Vec< Byte > = Vec::new(); - buffer.resize( 1024 * 1024, Byte( 1 ) ); - let mut buffer = buffer.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap(); - - buffer = black_box( buffer ); - b.iter( || { - let deserialized: Vec< Byte > = Readable::read_from_buffer_copying_data_with_ctx( Endianness::NATIVE, &buffer ).unwrap(); +fn read_speedy_megabyte_buffer_vec_non_primitive(b: &mut Bencher) { + let mut buffer: Vec = Vec::new(); + buffer.resize(1024 * 1024, Byte(1)); + let mut buffer = buffer.write_to_vec_with_ctx(Endianness::NATIVE).unwrap(); + + buffer = black_box(buffer); + b.iter(|| { + let deserialized: Vec = + Readable::read_from_buffer_copying_data_with_ctx(Endianness::NATIVE, &buffer).unwrap(); deserialized }) } @@ -107,12 +114,12 @@ struct Dummy { d: u8, e: f32, f: f64, - g: bool + g: bool, } #[bench] -fn read_speedy_many_small_structs( b: &mut Bencher ) { - let mut buffer: Vec< Dummy > = Vec::new(); +fn read_speedy_many_small_structs(b: &mut Bencher) { + let mut buffer: Vec = Vec::new(); let dummy = Dummy { a: 1, b: 2, @@ -120,21 +127,22 @@ fn read_speedy_many_small_structs( b: &mut Bencher ) { d: 4, e: 5.0, f: 6.0, - g: true + g: true, }; - buffer.resize( 1024 * 1024, dummy ); - let mut buffer = buffer.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap(); + buffer.resize(1024 * 1024, dummy); + let mut buffer = buffer.write_to_vec_with_ctx(Endianness::NATIVE).unwrap(); - buffer = black_box( buffer ); - b.iter( || { - let deserialized: Vec< Dummy > = Readable::read_from_buffer_copying_data_with_ctx( Endianness::NATIVE, &buffer ).unwrap(); + buffer = black_box(buffer); + b.iter(|| { + let deserialized: Vec = + Readable::read_from_buffer_copying_data_with_ctx(Endianness::NATIVE, &buffer).unwrap(); deserialized }) } #[bench] -fn write_speedy_many_small_structs( b: &mut Bencher ) { - let mut buffer: Vec< Dummy > = Vec::new(); +fn write_speedy_many_small_structs(b: &mut Bencher) { + let mut buffer: Vec = Vec::new(); let dummy = Dummy { a: 1, b: 2, @@ -142,14 +150,12 @@ fn write_speedy_many_small_structs( b: &mut Bencher ) { d: 4, e: 5.0, f: 6.0, - g: true + g: true, }; - buffer.resize( 1024 * 1024, dummy ); + buffer.resize(1024 * 1024, dummy); - buffer = black_box( buffer ); - b.iter( || { - buffer.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap() - }) + buffer = black_box(buffer); + b.iter(|| buffer.write_to_vec_with_ctx(Endianness::NATIVE).unwrap()) } pub struct XorShift64 { @@ -157,11 +163,11 @@ pub struct XorShift64 { } impl XorShift64 { - pub fn new( seed: u64 ) -> XorShift64 { + pub fn new(seed: u64) -> XorShift64 { XorShift64 { a: seed } } - pub fn next( &mut self ) -> u64 { + pub fn next(&mut self) -> u64 { let mut x = self.a; x ^= x << 13; x ^= x >> 7; @@ -172,88 +178,103 @@ impl XorShift64 { } #[bench] -fn read_varint_random( b: &mut Bencher ) { +fn read_varint_random(b: &mut Bencher) { use speedy::private::VarInt64; let mut rng = XorShift64 { a: 1234 }; - let buffer: Vec< VarInt64 > = (0..1024 * 1024).into_iter().map( |_| (1_u64 << (rng.next() % 63)).into() ).collect(); - let mut buffer = buffer.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap(); + let buffer: Vec = (0..1024 * 1024) + .into_iter() + .map(|_| (1_u64 << (rng.next() % 63)).into()) + .collect(); + let mut buffer = buffer.write_to_vec_with_ctx(Endianness::NATIVE).unwrap(); - buffer = black_box( buffer ); - b.iter( || { - let deserialized: Vec< VarInt64 > = Readable::read_from_buffer_copying_data_with_ctx( Endianness::NATIVE, &buffer ).unwrap(); + buffer = black_box(buffer); + b.iter(|| { + let deserialized: Vec = + Readable::read_from_buffer_copying_data_with_ctx(Endianness::NATIVE, &buffer).unwrap(); deserialized }) } #[bench] -fn read_varint_always_one_byte( b: &mut Bencher ) { +fn read_varint_always_one_byte(b: &mut Bencher) { use speedy::private::VarInt64; let mut rng = XorShift64 { a: 1234 }; - let buffer: Vec< VarInt64 > = (0..1024 * 1024).into_iter().map( |_| (rng.next() % 100).into() ).collect(); - let mut buffer = buffer.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap(); + let buffer: Vec = (0..1024 * 1024) + .into_iter() + .map(|_| (rng.next() % 100).into()) + .collect(); + let mut buffer = buffer.write_to_vec_with_ctx(Endianness::NATIVE).unwrap(); - buffer = black_box( buffer ); - b.iter( || { - let deserialized: Vec< VarInt64 > = Readable::read_from_buffer_copying_data_with_ctx( Endianness::NATIVE, &buffer ).unwrap(); + buffer = black_box(buffer); + b.iter(|| { + let deserialized: Vec = + Readable::read_from_buffer_copying_data_with_ctx(Endianness::NATIVE, &buffer).unwrap(); deserialized }) } #[bench] -fn read_varint_always_eight_bytes( b: &mut Bencher ) { +fn read_varint_always_eight_bytes(b: &mut Bencher) { use speedy::private::VarInt64; let mut rng = XorShift64 { a: 1234 }; - let buffer: Vec< VarInt64 > = (0..1024 * 1024).into_iter().map( |_| ((rng.next() % 100) | (1 << 63)).into() ).collect(); - let mut buffer = buffer.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap(); + let buffer: Vec = (0..1024 * 1024) + .into_iter() + .map(|_| ((rng.next() % 100) | (1 << 63)).into()) + .collect(); + let mut buffer = buffer.write_to_vec_with_ctx(Endianness::NATIVE).unwrap(); - buffer = black_box( buffer ); - b.iter( || { - let deserialized: Vec< VarInt64 > = Readable::read_from_buffer_copying_data_with_ctx( Endianness::NATIVE, &buffer ).unwrap(); + buffer = black_box(buffer); + b.iter(|| { + let deserialized: Vec = + Readable::read_from_buffer_copying_data_with_ctx(Endianness::NATIVE, &buffer).unwrap(); deserialized }) } #[bench] -fn write_varint_random( b: &mut Bencher ) { +fn write_varint_random(b: &mut Bencher) { use speedy::private::VarInt64; let mut rng = XorShift64 { a: 1234 }; - let buffer: Vec< VarInt64 > = (0..1024 * 1024).into_iter().map( |_| (1_u64 << (rng.next() % 63)).into() ).collect(); - let mut buffer = buffer.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap(); + let buffer: Vec = (0..1024 * 1024) + .into_iter() + .map(|_| (1_u64 << (rng.next() % 63)).into()) + .collect(); + let mut buffer = buffer.write_to_vec_with_ctx(Endianness::NATIVE).unwrap(); - buffer = black_box( buffer ); - b.iter( || { - buffer.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap() - }) + buffer = black_box(buffer); + b.iter(|| buffer.write_to_vec_with_ctx(Endianness::NATIVE).unwrap()) } #[bench] -fn write_varint_always_one_byte( b: &mut Bencher ) { +fn write_varint_always_one_byte(b: &mut Bencher) { use speedy::private::VarInt64; let mut rng = XorShift64 { a: 1234 }; - let buffer: Vec< VarInt64 > = (0..1024 * 1024).into_iter().map( |_| (rng.next() % 100).into() ).collect(); - let mut buffer = buffer.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap(); + let buffer: Vec = (0..1024 * 1024) + .into_iter() + .map(|_| (rng.next() % 100).into()) + .collect(); + let mut buffer = buffer.write_to_vec_with_ctx(Endianness::NATIVE).unwrap(); - buffer = black_box( buffer ); - b.iter( || { - buffer.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap() - }) + buffer = black_box(buffer); + b.iter(|| buffer.write_to_vec_with_ctx(Endianness::NATIVE).unwrap()) } #[bench] -fn write_varint_always_eight_bytes( b: &mut Bencher ) { +fn write_varint_always_eight_bytes(b: &mut Bencher) { use speedy::private::VarInt64; let mut rng = XorShift64 { a: 1234 }; - let buffer: Vec< VarInt64 > = (0..1024 * 1024).into_iter().map( |_| ((rng.next() % 100) | (1 << 63)).into() ).collect(); - let mut buffer = buffer.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap(); + let buffer: Vec = (0..1024 * 1024) + .into_iter() + .map(|_| ((rng.next() % 100) | (1 << 63)).into()) + .collect(); + let mut buffer = buffer.write_to_vec_with_ctx(Endianness::NATIVE).unwrap(); - buffer = black_box( buffer ); - b.iter( || { - buffer.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap() - }) + buffer = black_box(buffer); + b.iter(|| buffer.write_to_vec_with_ctx(Endianness::NATIVE).unwrap()) } diff --git a/speedy-derive/src/lib.rs b/speedy-derive/src/lib.rs index b48d211..220baf5 100644 --- a/speedy-derive/src/lib.rs +++ b/speedy-derive/src/lib.rs @@ -1,4 +1,4 @@ -#![recursion_limit="128"] +#![recursion_limit = "128"] use std::collections::HashMap; use std::u32; @@ -17,104 +17,126 @@ use quote::ToTokens; use syn::spanned::Spanned; trait IterExt: Iterator + Sized { - fn collect_vec( self ) -> Vec< Self::Item > { + fn collect_vec(self) -> Vec { self.collect() } } -impl< T > IterExt for T where T: Iterator + Sized {} +impl IterExt for T where T: Iterator + Sized {} #[proc_macro_derive(Readable, attributes(speedy))] -pub fn readable( input: proc_macro::TokenStream ) -> proc_macro::TokenStream { - let input = parse_macro_input!( input as syn::DeriveInput ); - let tokens = impl_readable( input ).unwrap_or_else( |err| err.to_compile_error() ); - proc_macro::TokenStream::from( tokens ) +pub fn readable(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input = parse_macro_input!(input as syn::DeriveInput); + let tokens = impl_readable(input).unwrap_or_else(|err| err.to_compile_error()); + proc_macro::TokenStream::from(tokens) } #[proc_macro_derive(Writable, attributes(speedy))] -pub fn writable( input: proc_macro::TokenStream ) -> proc_macro::TokenStream { - let input = parse_macro_input!( input as syn::DeriveInput ); - let tokens = impl_writable( input ).unwrap_or_else( |err| err.to_compile_error() ); - proc_macro::TokenStream::from( tokens ) +pub fn writable(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input = parse_macro_input!(input as syn::DeriveInput); + let tokens = impl_writable(input).unwrap_or_else(|err| err.to_compile_error()); + proc_macro::TokenStream::from(tokens) } mod kw { - syn::custom_keyword!( length ); - syn::custom_keyword!( default_on_eof ); - syn::custom_keyword!( tag_type ); - syn::custom_keyword!( length_type ); - syn::custom_keyword!( tag ); - syn::custom_keyword!( skip ); - syn::custom_keyword!( constant_prefix ); - syn::custom_keyword!( peek_tag ); - syn::custom_keyword!( varint ); - - syn::custom_keyword!( u7 ); - syn::custom_keyword!( u8 ); - syn::custom_keyword!( u16 ); - syn::custom_keyword!( u32 ); - syn::custom_keyword!( u64 ); - syn::custom_keyword!( u64_varint ); + syn::custom_keyword!(length); + syn::custom_keyword!(default_on_eof); + syn::custom_keyword!(tag_type); + syn::custom_keyword!(length_type); + syn::custom_keyword!(tag); + syn::custom_keyword!(skip); + syn::custom_keyword!(constant_prefix); + syn::custom_keyword!(peek_tag); + syn::custom_keyword!(varint); + + syn::custom_keyword!(u7); + syn::custom_keyword!(u8); + syn::custom_keyword!(u16); + syn::custom_keyword!(u32); + syn::custom_keyword!(u64); + syn::custom_keyword!(u64_varint); } #[derive(Copy, Clone, PartialEq)] enum Trait { Readable, Writable, - ZeroCopyable { is_packed: bool } + ZeroCopyable { is_packed: bool }, } -fn uses_generics( input: &syn::DeriveInput ) -> bool { - input.generics.type_params().next().is_some() || - input.generics.lifetimes().next().is_some() || - input.generics.const_params().next().is_some() +fn uses_generics(input: &syn::DeriveInput) -> bool { + input.generics.type_params().next().is_some() + || input.generics.lifetimes().next().is_some() + || input.generics.const_params().next().is_some() } -fn possibly_uses_generic_ty( generic_types: &[&syn::Ident], ty: &syn::Type ) -> bool { +fn possibly_uses_generic_ty(generic_types: &[&syn::Ident], ty: &syn::Type) -> bool { match ty { - syn::Type::Path( syn::TypePath { qself: None, path: syn::Path { leading_colon: None, segments } } ) => { - segments.iter().any( |segment| { - if generic_types.iter().any( |&ident| *ident == segment.ident ) { + syn::Type::Path(syn::TypePath { + qself: None, + path: + syn::Path { + leading_colon: None, + segments, + }, + }) => { + segments.iter().any(|segment| { + if generic_types.iter().any(|&ident| *ident == segment.ident) { return true; } match segment.arguments { syn::PathArguments::None => false, - syn::PathArguments::AngleBracketed( syn::AngleBracketedGenericArguments { ref args, .. } ) => { - args.iter().any( |arg| { + syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments { + ref args, + .. + }) => { + args.iter().any(|arg| { match arg { - syn::GenericArgument::Lifetime( .. ) => false, - syn::GenericArgument::Type( inner_ty ) => possibly_uses_generic_ty( generic_types, inner_ty ), + syn::GenericArgument::Lifetime(..) => false, + syn::GenericArgument::Type(inner_ty) => { + possibly_uses_generic_ty(generic_types, inner_ty) + } // TODO: How to handle these? - syn::GenericArgument::Binding( .. ) => true, - syn::GenericArgument::Constraint( .. ) => true, - syn::GenericArgument::Const( .. ) => true + syn::GenericArgument::Binding(..) => true, + syn::GenericArgument::Constraint(..) => true, + syn::GenericArgument::Const(..) => true, } }) - }, - _ => true + } + _ => true, } }) - }, - syn::Type::Slice( syn::TypeSlice { elem, .. } ) => possibly_uses_generic_ty( generic_types, &elem ), - syn::Type::Tuple( syn::TypeTuple { elems, .. } ) => elems.iter().any( |elem| possibly_uses_generic_ty( generic_types, elem ) ), - syn::Type::Reference( syn::TypeReference { elem, .. } ) => possibly_uses_generic_ty( generic_types, &elem ), - syn::Type::Paren( syn::TypeParen { elem, .. } ) => possibly_uses_generic_ty( generic_types, &elem ), - syn::Type::Ptr( syn::TypePtr { elem, .. } ) => possibly_uses_generic_ty( generic_types, &elem ), - syn::Type::Group( syn::TypeGroup { elem, .. } ) => possibly_uses_generic_ty( generic_types, &elem ), - syn::Type::Array( syn::TypeArray { elem, len, .. } ) => { - if possibly_uses_generic_ty( generic_types, &elem ) { + } + syn::Type::Slice(syn::TypeSlice { elem, .. }) => { + possibly_uses_generic_ty(generic_types, &elem) + } + syn::Type::Tuple(syn::TypeTuple { elems, .. }) => elems + .iter() + .any(|elem| possibly_uses_generic_ty(generic_types, elem)), + syn::Type::Reference(syn::TypeReference { elem, .. }) => { + possibly_uses_generic_ty(generic_types, &elem) + } + syn::Type::Paren(syn::TypeParen { elem, .. }) => { + possibly_uses_generic_ty(generic_types, &elem) + } + syn::Type::Ptr(syn::TypePtr { elem, .. }) => possibly_uses_generic_ty(generic_types, &elem), + syn::Type::Group(syn::TypeGroup { elem, .. }) => { + possibly_uses_generic_ty(generic_types, &elem) + } + syn::Type::Array(syn::TypeArray { elem, len, .. }) => { + if possibly_uses_generic_ty(generic_types, &elem) { return true; } // This is probably too conservative. match len { - syn::Expr::Lit( .. ) => false, - _ => true + syn::Expr::Lit(..) => false, + _ => true, } - }, - syn::Type::Never( .. ) => false, - _ => true + } + syn::Type::Never(..) => false, + _ => true, } } @@ -129,81 +151,95 @@ fn test_possibly_uses_generic_ty() { } } - assert_test!( false, String ); - assert_test!( false, Cow<'a, BTreeMap> ); - assert_test!( false, Cow<'a, [u8]> ); - assert_test!( false, () ); - assert_test!( false, (u8) ); - assert_test!( false, (u8, u8) ); - assert_test!( false, &u8 ); - assert_test!( false, *const u8 ); - assert_test!( false, ! ); - assert_test!( false, [u8; 2] ); - assert_test!( true, T ); - assert_test!( true, Dummy::T ); - assert_test!( true, Cow<'a, BTreeMap> ); - assert_test!( true, Cow<'a, BTreeMap> ); - assert_test!( true, Cow<'a, [T]> ); - assert_test!( true, (T) ); - assert_test!( true, (u8, T) ); - assert_test!( true, &T ); - assert_test!( true, *const T ); - assert_test!( true, [T; 2] ); - assert_test!( true, Vec ); -} - -fn is_guaranteed_non_recursive( ty: &syn::Type ) -> bool { + assert_test!(false, String); + assert_test!(false, Cow<'a, BTreeMap>); + assert_test!(false, Cow<'a, [u8]>); + assert_test!(false, ()); + assert_test!(false, (u8)); + assert_test!(false, (u8, u8)); + assert_test!(false, &u8); + assert_test!(false, *const u8); + assert_test!(false, !); + assert_test!(false, [u8; 2]); + assert_test!(true, T); + assert_test!(true, Dummy::T); + assert_test!(true, Cow<'a, BTreeMap>); + assert_test!(true, Cow<'a, BTreeMap>); + assert_test!(true, Cow<'a, [T]>); + assert_test!(true, (T)); + assert_test!(true, (u8, T)); + assert_test!(true, &T); + assert_test!(true, *const T); + assert_test!(true, [T; 2]); + assert_test!(true, Vec); +} + +fn is_guaranteed_non_recursive(ty: &syn::Type) -> bool { match ty { - syn::Type::Path( syn::TypePath { qself: None, path: syn::Path { leading_colon: None, segments } } ) => { + syn::Type::Path(syn::TypePath { + qself: None, + path: + syn::Path { + leading_colon: None, + segments, + }, + }) => { if segments.len() != 1 { return false; } - let segment = &segments[ 0 ]; + let segment = &segments[0]; let ident = segment.ident.to_string(); match ident.as_str() { - "String" | "Vec" | "BTreeSet" | "BTreeMap" | "HashSet" | "HashMap" | - "u8" | "u16" | "u32" | "u64" | "i8" | "i16" | "i32" | "i64" | "usize" | "isize" | - "str" => {}, - _ => return false + "String" | "Vec" | "BTreeSet" | "BTreeMap" | "HashSet" | "HashMap" | "u8" + | "u16" | "u32" | "u64" | "i8" | "i16" | "i32" | "i64" | "usize" | "isize" + | "str" => {} + _ => return false, } match segment.arguments { syn::PathArguments::None => true, - syn::PathArguments::AngleBracketed( syn::AngleBracketedGenericArguments { ref args, .. } ) => { - args.iter().all( |arg| { - match arg { - syn::GenericArgument::Lifetime( .. ) => true, - syn::GenericArgument::Type( inner_ty ) => is_guaranteed_non_recursive( inner_ty ), - // TODO: How to handle these? - syn::GenericArgument::Binding( .. ) => false, - syn::GenericArgument::Constraint( .. ) => false, - syn::GenericArgument::Const( .. ) => false + syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments { + ref args, + .. + }) => { + args.iter().all(|arg| { + match arg { + syn::GenericArgument::Lifetime(..) => true, + syn::GenericArgument::Type(inner_ty) => { + is_guaranteed_non_recursive(inner_ty) } - }) - }, - _ => false + // TODO: How to handle these? + syn::GenericArgument::Binding(..) => false, + syn::GenericArgument::Constraint(..) => false, + syn::GenericArgument::Const(..) => false, + } + }) + } + _ => false, } - }, - syn::Type::Slice( syn::TypeSlice { elem, .. } ) => is_guaranteed_non_recursive( &elem ), - syn::Type::Tuple( syn::TypeTuple { elems, .. } ) => elems.iter().all( |elem| is_guaranteed_non_recursive( elem ) ), - syn::Type::Reference( syn::TypeReference { elem, .. } ) => is_guaranteed_non_recursive( &elem ), - syn::Type::Paren( syn::TypeParen { elem, .. } ) => is_guaranteed_non_recursive( &elem ), - syn::Type::Ptr( syn::TypePtr { elem, .. } ) => is_guaranteed_non_recursive( &elem ), - syn::Type::Group( syn::TypeGroup { elem, .. } ) => is_guaranteed_non_recursive( &elem ), - syn::Type::Array( syn::TypeArray { elem, len, .. } ) => { - if !is_guaranteed_non_recursive( &elem ) { + } + syn::Type::Slice(syn::TypeSlice { elem, .. }) => is_guaranteed_non_recursive(&elem), + syn::Type::Tuple(syn::TypeTuple { elems, .. }) => { + elems.iter().all(|elem| is_guaranteed_non_recursive(elem)) + } + syn::Type::Reference(syn::TypeReference { elem, .. }) => is_guaranteed_non_recursive(&elem), + syn::Type::Paren(syn::TypeParen { elem, .. }) => is_guaranteed_non_recursive(&elem), + syn::Type::Ptr(syn::TypePtr { elem, .. }) => is_guaranteed_non_recursive(&elem), + syn::Type::Group(syn::TypeGroup { elem, .. }) => is_guaranteed_non_recursive(&elem), + syn::Type::Array(syn::TypeArray { elem, len, .. }) => { + if !is_guaranteed_non_recursive(&elem) { return false; } // This is probably too conservative. match len { - syn::Expr::Lit( .. ) => true, - _ => false + syn::Expr::Lit(..) => true, + _ => false, } - }, - syn::Type::Never( .. ) => true, - _ => false + } + syn::Type::Never(..) => true, + _ => false, } } @@ -218,16 +254,16 @@ fn test_is_guaranteed_non_recursive() { } } - assert_test!( true, String ); - assert_test!( true, u8 ); - assert_test!( true, () ); - assert_test!( true, *const u8 ); - assert_test!( true, [u8; 2] ); - assert_test!( true, (u8, u16) ); - assert_test!( true, ! ); - assert_test!( true, Vec< u8 > ); - assert_test!( false, T ); - assert_test!( false, Vec< T > ); + assert_test!(true, String); + assert_test!(true, u8); + assert_test!(true, ()); + assert_test!(true, *const u8); + assert_test!(true, [u8; 2]); + assert_test!(true, (u8, u16)); + assert_test!(true, !); + assert_test!(true, Vec); + assert_test!(false, T); + assert_test!(false, Vec); } #[derive(Copy, Clone, PartialEq, Eq)] @@ -243,52 +279,66 @@ enum PrimitiveTy { I64, I128, F32, - F64 + F64, } -fn parse_primitive_ty( ty: &syn::Type ) -> Option< PrimitiveTy > { +fn parse_primitive_ty(ty: &syn::Type) -> Option { match ty { - syn::Type::Path( syn::TypePath { qself: None, path: syn::Path { leading_colon: None, segments } } ) => { + syn::Type::Path(syn::TypePath { + qself: None, + path: + syn::Path { + leading_colon: None, + segments, + }, + }) => { if segments.len() != 1 { return None; } - let segment = &segments[ 0 ]; + let segment = &segments[0]; let ident = segment.ident.to_string(); match ident.as_str() { - "u8" => Some( PrimitiveTy::U8 ), - "u16" => Some( PrimitiveTy::U16 ), - "u32" => Some( PrimitiveTy::U32 ), - "u64" => Some( PrimitiveTy::U64 ), - "u128" => Some( PrimitiveTy::U128 ), - "i8" => Some( PrimitiveTy::I8 ), - "i16" => Some( PrimitiveTy::I16 ), - "i32" => Some( PrimitiveTy::I32 ), - "i64" => Some( PrimitiveTy::I64 ), - "i128" => Some( PrimitiveTy::I128 ), - "f32" => Some( PrimitiveTy::F32 ), - "f64" => Some( PrimitiveTy::F64 ), - _ => None + "u8" => Some(PrimitiveTy::U8), + "u16" => Some(PrimitiveTy::U16), + "u32" => Some(PrimitiveTy::U32), + "u64" => Some(PrimitiveTy::U64), + "u128" => Some(PrimitiveTy::U128), + "i8" => Some(PrimitiveTy::I8), + "i16" => Some(PrimitiveTy::I16), + "i32" => Some(PrimitiveTy::I32), + "i64" => Some(PrimitiveTy::I64), + "i128" => Some(PrimitiveTy::I128), + "f32" => Some(PrimitiveTy::F32), + "f64" => Some(PrimitiveTy::F64), + _ => None, } - }, - _ => None + } + _ => None, } } -fn common_tokens( ast: &syn::DeriveInput, types: &[syn::Type], trait_variant: Trait ) -> (TokenStream, TokenStream, TokenStream) { +fn common_tokens( + ast: &syn::DeriveInput, + types: &[syn::Type], + trait_variant: Trait, +) -> (TokenStream, TokenStream, TokenStream) { let impl_params = { - let lifetime_params = ast.generics.lifetimes().map( |alpha| quote! { #alpha } ); - let type_params = ast.generics.type_params().map( |ty| quote! { #ty } ); - let params = lifetime_params.chain( type_params ).collect_vec(); + let lifetime_params = ast.generics.lifetimes().map(|alpha| quote! { #alpha }); + let type_params = ast.generics.type_params().map(|ty| quote! { #ty }); + let params = lifetime_params.chain(type_params).collect_vec(); quote! { #(#params,)* } }; let ty_params = { - let lifetime_params = ast.generics.lifetimes().map( |alpha| quote! { #alpha } ); - let type_params = ast.generics.type_params().map( |ty| { let ident = &ty.ident; quote! { #ident } } ); - let params = lifetime_params.chain( type_params ).collect_vec(); + let lifetime_params = ast.generics.lifetimes().map(|alpha| quote! { #alpha }); + let type_params = ast.generics.type_params().map(|ty| { + let ident = &ty.ident; + quote! { #ident } + }); + let params = lifetime_params.chain(type_params).collect_vec(); if params.is_empty() { quote! {} } else { @@ -296,38 +346,42 @@ fn common_tokens( ast: &syn::DeriveInput, types: &[syn::Type], trait_variant: Tr } }; - let generics: Vec< _ > = ast.generics.type_params().map( |ty| &ty.ident ).collect(); + let generics: Vec<_> = ast.generics.type_params().map(|ty| &ty.ident).collect(); let where_clause = { - let constraints = types.iter().filter_map( |ty| { - let possibly_generic = possibly_uses_generic_ty( &generics, ty ); + let constraints = types.iter().filter_map(|ty| { + let possibly_generic = possibly_uses_generic_ty(&generics, ty); match (trait_variant, possibly_generic) { - (Trait::Readable, true) => Some( quote! { #ty: speedy::Readable< 'a_, C_ > } ), + (Trait::Readable, true) => Some(quote! { #ty: speedy::Readable< 'a_, C_ > }), (Trait::Readable, false) => None, - (Trait::Writable, true) => Some( quote! { #ty: speedy::Writable< C_ > } ), + (Trait::Writable, true) => Some(quote! { #ty: speedy::Writable< C_ > }), (Trait::Writable, false) => None, (Trait::ZeroCopyable { is_packed }, _) => { - if is_packed && parse_primitive_ty( ty ).is_some() { + if is_packed && parse_primitive_ty(ty).is_some() { None } else { - Some( quote! { #ty: speedy::private::ZeroCopyable< T_ > } ) + Some(quote! { #ty: speedy::private::ZeroCopyable< T_ > }) } - }, + } } }); let mut predicates = Vec::new(); - if let Some( where_clause ) = ast.generics.where_clause.as_ref() { - predicates = where_clause.predicates.iter().map( |pred| quote! { #pred } ).collect(); + if let Some(where_clause) = ast.generics.where_clause.as_ref() { + predicates = where_clause + .predicates + .iter() + .map(|pred| quote! { #pred }) + .collect(); } if trait_variant == Trait::Readable { for lifetime in ast.generics.lifetimes() { - predicates.push( quote! { 'a_: #lifetime } ); - predicates.push( quote! { #lifetime: 'a_ } ); + predicates.push(quote! { 'a_: #lifetime }); + predicates.push(quote! { #lifetime: 'a_ }); } } - let items = constraints.chain( predicates.into_iter() ).collect_vec(); + let items = constraints.chain(predicates.into_iter()).collect_vec(); if items.is_empty() { quote! {} } else { @@ -345,166 +399,150 @@ enum BasicType { U16, U32, U64, - VarInt64 + VarInt64, } const DEFAULT_LENGTH_TYPE: BasicType = BasicType::U32; const DEFAULT_ENUM_TAG_TYPE: BasicType = BasicType::U32; impl syn::parse::Parse for BasicType { - fn parse( input: syn::parse::ParseStream ) -> syn::parse::Result< Self > { + fn parse(input: syn::parse::ParseStream) -> syn::parse::Result { let lookahead = input.lookahead1(); - let ty = if lookahead.peek( kw::u7 ) { - input.parse::< kw::u7 >()?; + let ty = if lookahead.peek(kw::u7) { + input.parse::()?; BasicType::U7 - } else if lookahead.peek( kw::u8 ) { - input.parse::< kw::u8 >()?; + } else if lookahead.peek(kw::u8) { + input.parse::()?; BasicType::U8 - } else if lookahead.peek( kw::u16 ) { - input.parse::< kw::u16 >()?; + } else if lookahead.peek(kw::u16) { + input.parse::()?; BasicType::U16 - } else if lookahead.peek( kw::u32 ) { - input.parse::< kw::u32 >()?; + } else if lookahead.peek(kw::u32) { + input.parse::()?; BasicType::U32 - } else if lookahead.peek( kw::u64 ) { - input.parse::< kw::u64 >()?; + } else if lookahead.peek(kw::u64) { + input.parse::()?; BasicType::U64 - } else if lookahead.peek( kw::u64_varint ) { - input.parse::< kw::u64_varint >()?; + } else if lookahead.peek(kw::u64_varint) { + input.parse::()?; BasicType::VarInt64 } else { - return Err( lookahead.error() ); + return Err(lookahead.error()); }; - Ok( ty ) + Ok(ty) } } enum VariantAttribute { - Tag { - key_token: kw::tag, - tag: u64 - } + Tag { key_token: kw::tag, tag: u64 }, } -enum StructAttribute { -} +enum StructAttribute {} enum EnumAttribute { TagType { key_token: kw::tag_type, - ty: BasicType + ty: BasicType, }, PeekTag { - key_token: kw::peek_tag - } + key_token: kw::peek_tag, + }, } enum VariantOrStructAttribute { - Variant( VariantAttribute ), - Struct( StructAttribute ) + Variant(VariantAttribute), + Struct(StructAttribute), } fn parse_variant_attribute( input: &syn::parse::ParseStream, - lookahead: &syn::parse::Lookahead1 -) -> syn::parse::Result< Option< VariantAttribute > > -{ - let attribute = if lookahead.peek( kw::tag ) { - let key_token = input.parse::< kw::tag >()?; + lookahead: &syn::parse::Lookahead1, +) -> syn::parse::Result> { + let attribute = if lookahead.peek(kw::tag) { + let key_token = input.parse::()?; let _: Token![=] = input.parse()?; let raw_tag: syn::LitInt = input.parse()?; - let tag = raw_tag.base10_parse::< u64 >().map_err( |err| { - syn::Error::new( raw_tag.span(), err ) - })?; + let tag = raw_tag + .base10_parse::() + .map_err(|err| syn::Error::new(raw_tag.span(), err))?; - VariantAttribute::Tag { - key_token, - tag - } + VariantAttribute::Tag { key_token, tag } } else { - return Ok( None ) + return Ok(None); }; - Ok( Some( attribute ) ) + Ok(Some(attribute)) } fn parse_struct_attribute( _input: &syn::parse::ParseStream, - _lookahead: &syn::parse::Lookahead1 -) -> syn::parse::Result< Option< StructAttribute > > -{ - Ok( None ) + _lookahead: &syn::parse::Lookahead1, +) -> syn::parse::Result> { + Ok(None) } fn parse_enum_attribute( input: &syn::parse::ParseStream, - lookahead: &syn::parse::Lookahead1 -) -> syn::parse::Result< Option< EnumAttribute > > -{ - let attribute = if lookahead.peek( kw::tag_type ) { - let key_token = input.parse::< kw::tag_type >()?; + lookahead: &syn::parse::Lookahead1, +) -> syn::parse::Result> { + let attribute = if lookahead.peek(kw::tag_type) { + let key_token = input.parse::()?; let _: Token![=] = input.parse()?; let ty: BasicType = input.parse()?; - EnumAttribute::TagType { - key_token, - ty - } - } else if lookahead.peek( kw::peek_tag ) { - let key_token = input.parse::< kw::peek_tag >()?; - EnumAttribute::PeekTag { - key_token - } + EnumAttribute::TagType { key_token, ty } + } else if lookahead.peek(kw::peek_tag) { + let key_token = input.parse::()?; + EnumAttribute::PeekTag { key_token } } else { - return Ok( None ) + return Ok(None); }; - Ok( Some( attribute ) ) + Ok(Some(attribute)) } impl syn::parse::Parse for StructAttribute { - fn parse( input: syn::parse::ParseStream ) -> syn::parse::Result< Self > { + fn parse(input: syn::parse::ParseStream) -> syn::parse::Result { let lookahead = input.lookahead1(); - parse_struct_attribute( &input, &lookahead )?.ok_or_else( || lookahead.error() ) + parse_struct_attribute(&input, &lookahead)?.ok_or_else(|| lookahead.error()) } } impl syn::parse::Parse for EnumAttribute { - fn parse( input: syn::parse::ParseStream ) -> syn::parse::Result< Self > { + fn parse(input: syn::parse::ParseStream) -> syn::parse::Result { let lookahead = input.lookahead1(); - parse_enum_attribute( &input, &lookahead )?.ok_or_else( || lookahead.error() ) + parse_enum_attribute(&input, &lookahead)?.ok_or_else(|| lookahead.error()) } } impl syn::parse::Parse for VariantOrStructAttribute { - fn parse( input: syn::parse::ParseStream ) -> syn::parse::Result< Self > { + fn parse(input: syn::parse::ParseStream) -> syn::parse::Result { let lookahead = input.lookahead1(); - if let Some( attr ) = parse_variant_attribute( &input, &lookahead )? { - return Ok( VariantOrStructAttribute::Variant( attr ) ); + if let Some(attr) = parse_variant_attribute(&input, &lookahead)? { + return Ok(VariantOrStructAttribute::Variant(attr)); } - if let Some( attr ) = parse_struct_attribute( &input, &lookahead )? { - return Ok( VariantOrStructAttribute::Struct( attr ) ); + if let Some(attr) = parse_struct_attribute(&input, &lookahead)? { + return Ok(VariantOrStructAttribute::Struct(attr)); } - Err( lookahead.error() ) + Err(lookahead.error()) } } struct VariantAttributes { - tag: Option< u64 > + tag: Option, } -struct StructAttributes { -} +struct StructAttributes {} struct EnumAttributes { - tag_type: Option< BasicType >, - peek_tag: bool + tag_type: Option, + peek_tag: bool, } -fn check_repr( attrs: &[syn::Attribute], value: &str ) -> bool { +fn check_repr(attrs: &[syn::Attribute], value: &str) -> bool { let mut result = false; for raw_attr in attrs { let path = raw_attr.path.clone().into_token_stream().to_string(); @@ -518,26 +556,32 @@ fn check_repr( attrs: &[syn::Attribute], value: &str ) -> bool { result } -fn is_transparent( attrs: &[syn::Attribute] ) -> bool { - check_repr( attrs, "(transparent)" ) +fn is_transparent(attrs: &[syn::Attribute]) -> bool { + check_repr(attrs, "(transparent)") } -fn is_packed( attrs: &[syn::Attribute] ) -> bool { - check_repr( attrs, "(packed)" ) +fn is_packed(attrs: &[syn::Attribute]) -> bool { + check_repr(attrs, "(packed)") } -fn is_c( attrs: &[syn::Attribute] ) -> bool { - check_repr( attrs, "(C)" ) +fn is_c(attrs: &[syn::Attribute]) -> bool { + check_repr(attrs, "(C)") } -fn parse_attributes< T >( attrs: &[syn::Attribute] ) -> Result< Vec< T >, syn::Error > where T: syn::parse::Parse { - struct RawAttributes< T >( syn::punctuated::Punctuated< T, Token![,] > ); +fn parse_attributes(attrs: &[syn::Attribute]) -> Result, syn::Error> +where + T: syn::parse::Parse, +{ + struct RawAttributes(syn::punctuated::Punctuated); - impl< T > syn::parse::Parse for RawAttributes< T > where T: syn::parse::Parse { - fn parse( input: syn::parse::ParseStream ) -> syn::parse::Result< Self > { + impl syn::parse::Parse for RawAttributes + where + T: syn::parse::Parse, + { + fn parse(input: syn::parse::ParseStream) -> syn::parse::Result { let content; parenthesized!( content in input ); - Ok( RawAttributes( content.parse_terminated( T::parse )? ) ) + Ok(RawAttributes(content.parse_terminated(T::parse)?)) } } @@ -548,43 +592,41 @@ fn parse_attributes< T >( attrs: &[syn::Attribute] ) -> Result< Vec< T >, syn::E continue; } - let parsed_attrs: RawAttributes< T > = syn::parse2( raw_attr.tokens.clone() )?; + let parsed_attrs: RawAttributes = syn::parse2(raw_attr.tokens.clone())?; for attr in parsed_attrs.0 { - output.push( attr ); + output.push(attr); } } - Ok( output ) + Ok(output) } -fn collect_variant_attributes( attrs: Vec< VariantAttribute > ) -> Result< VariantAttributes, syn::Error > { +fn collect_variant_attributes( + attrs: Vec, +) -> Result { let mut variant_tag = None; for attr in attrs { match attr { VariantAttribute::Tag { key_token, tag } => { if variant_tag.is_some() { let message = "Duplicate 'tag'"; - return Err( syn::Error::new( key_token.span(), message ) ); + return Err(syn::Error::new(key_token.span(), message)); } - variant_tag = Some( tag ); + variant_tag = Some(tag); } } } - Ok( VariantAttributes { - tag: variant_tag - }) + Ok(VariantAttributes { tag: variant_tag }) } -fn collect_struct_attributes( attrs: Vec< StructAttribute > ) -> Result< StructAttributes, syn::Error > { - for _attr in attrs { - } +fn collect_struct_attributes(attrs: Vec) -> Result { + for _attr in attrs {} - Ok( StructAttributes { - }) + Ok(StructAttributes {}) } -fn collect_enum_attributes( attrs: Vec< EnumAttribute > ) -> Result< EnumAttributes, syn::Error > { +fn collect_enum_attributes(attrs: Vec) -> Result { let mut tag_type = None; let mut peek_tag = false; for attr in attrs { @@ -592,514 +634,570 @@ fn collect_enum_attributes( attrs: Vec< EnumAttribute > ) -> Result< EnumAttribu EnumAttribute::TagType { key_token, ty } => { if tag_type.is_some() { let message = "Duplicate 'tag_type'"; - return Err( syn::Error::new( key_token.span(), message ) ); + return Err(syn::Error::new(key_token.span(), message)); } - tag_type = Some( ty ); - }, + tag_type = Some(ty); + } EnumAttribute::PeekTag { key_token } => { if peek_tag { let message = "Duplicate 'peek_tag'"; - return Err( syn::Error::new( key_token.span(), message ) ); + return Err(syn::Error::new(key_token.span(), message)); } peek_tag = true; } } } - Ok( EnumAttributes { - tag_type, - peek_tag - }) + Ok(EnumAttributes { tag_type, peek_tag }) } #[derive(PartialEq)] enum StructKind { Unit, Named, - Unnamed + Unnamed, } -struct Struct< 'a > { - fields: Vec< Field< 'a > >, - kind: StructKind +struct Struct<'a> { + fields: Vec>, + kind: StructKind, } -impl< 'a > Struct< 'a > { - fn new( fields: &'a syn::Fields, attrs: Vec< StructAttribute > ) -> Result< Self, syn::Error > { - collect_struct_attributes( attrs )?; +impl<'a> Struct<'a> { + fn new(fields: &'a syn::Fields, attrs: Vec) -> Result { + collect_struct_attributes(attrs)?; let structure = match fields { - syn::Fields::Unit => { - Struct { - fields: Vec::new(), - kind: StructKind::Unit - } + syn::Fields::Unit => Struct { + fields: Vec::new(), + kind: StructKind::Unit, }, - syn::Fields::Named( syn::FieldsNamed { ref named, .. } ) => { - Struct { - fields: get_fields( named.into_iter() )?, - kind: StructKind::Named - } + syn::Fields::Named(syn::FieldsNamed { ref named, .. }) => Struct { + fields: get_fields(named.into_iter())?, + kind: StructKind::Named, + }, + syn::Fields::Unnamed(syn::FieldsUnnamed { ref unnamed, .. }) => Struct { + fields: get_fields(unnamed.into_iter())?, + kind: StructKind::Unnamed, }, - syn::Fields::Unnamed( syn::FieldsUnnamed { ref unnamed, .. } ) => { - Struct { - fields: get_fields( unnamed.into_iter() )?, - kind: StructKind::Unnamed - } - } }; - Ok( structure ) + Ok(structure) } - fn is_guaranteed_non_recursive( &self ) -> bool { - self.fields.iter().all( |field| field.is_guaranteed_non_recursive() ) + fn is_guaranteed_non_recursive(&self) -> bool { + self.fields + .iter() + .all(|field| field.is_guaranteed_non_recursive()) } } -struct Field< 'a > { +struct Field<'a> { index: usize, - name: Option< &'a syn::Ident >, + name: Option<&'a syn::Ident>, raw_ty: &'a syn::Type, default_on_eof: bool, - length: Option< LengthKind >, - length_type: Option< BasicType >, - ty: Opt< Ty >, + length: Option, + length_type: Option, + ty: Opt, skip: bool, varint: bool, - constant_prefix: Option< syn::LitByteStr > + constant_prefix: Option, } -impl< 'a > Field< 'a > { - fn can_be_primitive( &self ) -> bool { - self.default_on_eof == false && - self.length.is_none() && - self.length_type.is_none() && - self.skip == false && - self.varint == false && - self.constant_prefix.is_none() +impl<'a> Field<'a> { + fn can_be_primitive(&self) -> bool { + self.default_on_eof == false + && self.length.is_none() + && self.length_type.is_none() + && self.skip == false + && self.varint == false + && self.constant_prefix.is_none() } - fn is_simple( &self ) -> bool { - parse_primitive_ty( self.raw_ty ).is_some() + fn is_simple(&self) -> bool { + parse_primitive_ty(self.raw_ty).is_some() } - fn var_name( &self ) -> syn::Ident { - if let Some( name ) = self.name { + fn var_name(&self) -> syn::Ident { + if let Some(name) = self.name { name.clone() } else { - syn::Ident::new( &format!( "t{}", self.index ), Span::call_site() ) + syn::Ident::new(&format!("t{}", self.index), Span::call_site()) } } - fn name( &self ) -> syn::Member { - if let Some( name ) = self.name { - syn::Member::Named( name.clone() ) + fn name(&self) -> syn::Member { + if let Some(name) = self.name { + syn::Member::Named(name.clone()) } else { - syn::Member::Unnamed( syn::Index { index: self.index as u32, span: Span::call_site() } ) + syn::Member::Unnamed(syn::Index { + index: self.index as u32, + span: Span::call_site(), + }) } } - fn bound_types( &self ) -> Vec< syn::Type > { + fn bound_types(&self) -> Vec { match self.ty.inner() { - | Ty::Array( inner_ty, .. ) - | Ty::Vec( inner_ty ) - | Ty::HashSet( inner_ty ) - | Ty::BTreeSet( inner_ty ) - | Ty::CowHashSet( _, inner_ty ) - | Ty::CowBTreeSet( _, inner_ty ) - | Ty::CowSlice( _, inner_ty ) - | Ty::RefSlice( _, inner_ty ) - => vec![ inner_ty.clone() ], - | Ty::HashMap( key_ty, value_ty ) - | Ty::BTreeMap( key_ty, value_ty ) - | Ty::CowHashMap( _, key_ty, value_ty ) - | Ty::CowBTreeMap( _, key_ty, value_ty ) - => vec![ key_ty.clone(), value_ty.clone() ], - | Ty::RefSliceU8( _ ) - | Ty::RefStr( _ ) - | Ty::String - | Ty::CowStr( .. ) - | Ty::Primitive( .. ) - => vec![], - | Ty::Ty( _ ) => vec![ self.raw_ty.clone() ] + Ty::Array(inner_ty, ..) + | Ty::Vec(inner_ty) + | Ty::HashSet(inner_ty) + | Ty::BTreeSet(inner_ty) + | Ty::CowHashSet(_, inner_ty) + | Ty::CowBTreeSet(_, inner_ty) + | Ty::CowSlice(_, inner_ty) + | Ty::RefSlice(_, inner_ty) => vec![inner_ty.clone()], + Ty::HashMap(key_ty, value_ty) + | Ty::BTreeMap(key_ty, value_ty) + | Ty::CowHashMap(_, key_ty, value_ty) + | Ty::CowBTreeMap(_, key_ty, value_ty) => vec![key_ty.clone(), value_ty.clone()], + Ty::RefSliceU8(_) | Ty::RefStr(_) | Ty::String | Ty::CowStr(..) | Ty::Primitive(..) => { + vec![] + } + Ty::Ty(_) => vec![self.raw_ty.clone()], } } - fn is_guaranteed_non_recursive( &self ) -> bool { - is_guaranteed_non_recursive( &self.raw_ty ) + fn is_guaranteed_non_recursive(&self) -> bool { + is_guaranteed_non_recursive(&self.raw_ty) } } enum LengthKind { - Expr( syn::Expr ), - UntilEndOfFile + Expr(syn::Expr), + UntilEndOfFile, } impl syn::parse::Parse for LengthKind { - fn parse( input: syn::parse::ParseStream ) -> syn::parse::Result< Self > { - if input.peek( Token![..] ) { + fn parse(input: syn::parse::ParseStream) -> syn::parse::Result { + if input.peek(Token![..]) { let _: Token![..] = input.parse()?; - Ok( LengthKind::UntilEndOfFile ) + Ok(LengthKind::UntilEndOfFile) } else { let expr: syn::Expr = input.parse()?; - Ok( LengthKind::Expr( expr ) ) + Ok(LengthKind::Expr(expr)) } } } enum FieldAttribute { DefaultOnEof { - key_span: Span + key_span: Span, }, Length { key_span: Span, - length_kind: LengthKind + length_kind: LengthKind, }, LengthType { key_span: Span, - ty: BasicType + ty: BasicType, }, Skip { - key_span: Span + key_span: Span, }, ConstantPrefix { key_span: Span, - prefix: syn::LitByteStr + prefix: syn::LitByteStr, }, VarInt { - key_span: Span - } + key_span: Span, + }, } impl syn::parse::Parse for FieldAttribute { - fn parse( input: syn::parse::ParseStream ) -> syn::parse::Result< Self > { + fn parse(input: syn::parse::ParseStream) -> syn::parse::Result { let lookahead = input.lookahead1(); - let value = if lookahead.peek( kw::default_on_eof ) { - let key_token = input.parse::< kw::default_on_eof >()?; + let value = if lookahead.peek(kw::default_on_eof) { + let key_token = input.parse::()?; FieldAttribute::DefaultOnEof { - key_span: key_token.span() + key_span: key_token.span(), } - } else if lookahead.peek( kw::length ) { - let key_token = input.parse::< kw::length >()?; + } else if lookahead.peek(kw::length) { + let key_token = input.parse::()?; let _: Token![=] = input.parse()?; let length_kind: LengthKind = input.parse()?; FieldAttribute::Length { key_span: key_token.span(), - length_kind + length_kind, } - } else if lookahead.peek( kw::length_type ) { - let key_token = input.parse::< kw::length_type>()?; + } else if lookahead.peek(kw::length_type) { + let key_token = input.parse::()?; let _: Token![=] = input.parse()?; let ty: BasicType = input.parse()?; FieldAttribute::LengthType { key_span: key_token.span(), - ty + ty, } - } else if lookahead.peek( kw::skip ) { - let key_token = input.parse::< kw::skip >()?; + } else if lookahead.peek(kw::skip) { + let key_token = input.parse::()?; FieldAttribute::Skip { - key_span: key_token.span() + key_span: key_token.span(), } - } else if lookahead.peek( kw::constant_prefix ) { - let key_token = input.parse::< kw::constant_prefix >()?; + } else if lookahead.peek(kw::constant_prefix) { + let key_token = input.parse::()?; let _: Token![=] = input.parse()?; let expr: syn::Expr = input.parse()?; let value_span = expr.span(); let generic_error = || { - Err( syn::Error::new( value_span, "unsupported expression; only basic literals are supported" ) ) + Err(syn::Error::new( + value_span, + "unsupported expression; only basic literals are supported", + )) }; let prefix = match expr { - syn::Expr::Lit( literal ) => { + syn::Expr::Lit(literal) => { let literal = literal.lit; match literal { - syn::Lit::Str( literal ) => literal.value().into_bytes(), - syn::Lit::ByteStr( literal ) => literal.value(), - syn::Lit::Byte( literal ) => vec![ literal.value() ], - syn::Lit::Char( literal ) => format!( "{}", literal.value() ).into_bytes(), - syn::Lit::Bool( literal ) => vec![ if literal.value { 1 } else { 0 } ], - syn::Lit::Int( literal ) => { + syn::Lit::Str(literal) => literal.value().into_bytes(), + syn::Lit::ByteStr(literal) => literal.value(), + syn::Lit::Byte(literal) => vec![literal.value()], + syn::Lit::Char(literal) => format!("{}", literal.value()).into_bytes(), + syn::Lit::Bool(literal) => vec![if literal.value { 1 } else { 0 }], + syn::Lit::Int(literal) => { if literal.suffix() == "u8" { - vec![ literal.base10_parse::< u8 >().unwrap() ] + vec![literal.base10_parse::().unwrap()] } else { return Err( syn::Error::new( value_span, "integers are not supported; if you want to use a single byte constant then append either 'u8' or 'i8' to it" ) ); } - }, - syn::Lit::Float( _ ) => return Err( syn::Error::new( value_span, "floats are not supported" ) ), - syn::Lit::Verbatim( _ ) => return Err( syn::Error::new( value_span, "verbatim literals are not supported" ) ) + } + syn::Lit::Float(_) => { + return Err(syn::Error::new(value_span, "floats are not supported")) + } + syn::Lit::Verbatim(_) => { + return Err(syn::Error::new( + value_span, + "verbatim literals are not supported", + )) + } } - }, - syn::Expr::Unary( syn::ExprUnary { op: syn::UnOp::Neg(_), expr, .. } ) => { - match *expr { - syn::Expr::Lit( syn::ExprLit { lit: literal, .. } ) => { - match literal { - syn::Lit::Int( literal ) => { - if literal.suffix() == "i8" { - vec![ (literal.base10_parse::< i8 >().unwrap() * -1) as u8 ] - } else if literal.suffix() == "u8" { - return generic_error() - } else { - return Err( syn::Error::new( value_span, "integers are not supported; if you want to use a single byte constant then append either 'u8' or 'i8' to it" ) ); - } - }, - _ => return generic_error() + } + syn::Expr::Unary(syn::ExprUnary { + op: syn::UnOp::Neg(_), + expr, + .. + }) => match *expr { + syn::Expr::Lit(syn::ExprLit { lit: literal, .. }) => match literal { + syn::Lit::Int(literal) => { + if literal.suffix() == "i8" { + vec![(literal.base10_parse::().unwrap() * -1) as u8] + } else if literal.suffix() == "u8" { + return generic_error(); + } else { + return Err( syn::Error::new( value_span, "integers are not supported; if you want to use a single byte constant then append either 'u8' or 'i8' to it" ) ); } - }, - _ => return generic_error() - } + } + _ => return generic_error(), + }, + _ => return generic_error(), }, - _ => return generic_error() + _ => return generic_error(), }; FieldAttribute::ConstantPrefix { key_span: key_token.span(), - prefix: syn::LitByteStr::new( &prefix, value_span ) + prefix: syn::LitByteStr::new(&prefix, value_span), } - } else if lookahead.peek( kw::varint ) { - let key_token = input.parse::< kw::varint >()?; + } else if lookahead.peek(kw::varint) { + let key_token = input.parse::()?; FieldAttribute::VarInt { - key_span: key_token.span() + key_span: key_token.span(), } } else { - return Err( lookahead.error() ) + return Err(lookahead.error()); }; - Ok( value ) + Ok(value) } } -enum Opt< T > { - Plain( T ), - Option( T ) +enum Opt { + Plain(T), + Option(T), } -impl< T > Opt< T > { - fn inner( &self ) -> &T { +impl Opt { + fn inner(&self) -> &T { match *self { - Opt::Option( ref inner ) => inner, - Opt::Plain( ref inner ) => inner + Opt::Option(ref inner) => inner, + Opt::Plain(ref inner) => inner, } } } enum Ty { String, - Vec( syn::Type ), - CowSlice( syn::Lifetime, syn::Type ), - CowStr( syn::Lifetime ), - HashMap( syn::Type, syn::Type ), - HashSet( syn::Type ), - BTreeMap( syn::Type, syn::Type ), - BTreeSet( syn::Type ), + Vec(syn::Type), + CowSlice(syn::Lifetime, syn::Type), + CowStr(syn::Lifetime), + HashMap(syn::Type, syn::Type), + HashSet(syn::Type), + BTreeMap(syn::Type, syn::Type), + BTreeSet(syn::Type), - CowHashMap( syn::Lifetime, syn::Type, syn::Type ), - CowHashSet( syn::Lifetime, syn::Type ), - CowBTreeMap( syn::Lifetime, syn::Type, syn::Type ), - CowBTreeSet( syn::Lifetime, syn::Type ), + CowHashMap(syn::Lifetime, syn::Type, syn::Type), + CowHashSet(syn::Lifetime, syn::Type), + CowBTreeMap(syn::Lifetime, syn::Type, syn::Type), + CowBTreeSet(syn::Lifetime, syn::Type), - RefSliceU8( syn::Lifetime ), - RefSlice( syn::Lifetime, syn::Type ), - RefStr( syn::Lifetime ), + RefSliceU8(syn::Lifetime), + RefSlice(syn::Lifetime, syn::Type), + RefStr(syn::Lifetime), - Array( syn::Type, u32 ), + Array(syn::Type, u32), - Primitive( PrimitiveTy ), - Ty( syn::Type ) + Primitive(PrimitiveTy), + Ty(syn::Type), } -fn extract_inner_ty( args: &syn::punctuated::Punctuated< syn::GenericArgument, syn::token::Comma > ) -> Option< &syn::Type > { +fn extract_inner_ty( + args: &syn::punctuated::Punctuated, +) -> Option<&syn::Type> { if args.len() != 1 { return None; } - match args[ 0 ] { - syn::GenericArgument::Type( ref ty ) => Some( ty ), - _ => None + match args[0] { + syn::GenericArgument::Type(ref ty) => Some(ty), + _ => None, } } -fn extract_inner_ty_2( args: &syn::punctuated::Punctuated< syn::GenericArgument, syn::token::Comma > ) -> Option< (&syn::Type, &syn::Type) > { +fn extract_inner_ty_2( + args: &syn::punctuated::Punctuated, +) -> Option<(&syn::Type, &syn::Type)> { if args.len() != 2 { return None; } - let ty_1 = match args[ 0 ] { - syn::GenericArgument::Type( ref ty ) => ty, - _ => return None + let ty_1 = match args[0] { + syn::GenericArgument::Type(ref ty) => ty, + _ => return None, }; - let ty_2 = match args[ 1 ] { - syn::GenericArgument::Type( ref ty ) => ty, - _ => return None + let ty_2 = match args[1] { + syn::GenericArgument::Type(ref ty) => ty, + _ => return None, }; - Some( (ty_1, ty_2) ) + Some((ty_1, ty_2)) } -fn extract_lifetime_and_inner_ty( args: &syn::punctuated::Punctuated< syn::GenericArgument, syn::token::Comma > ) -> Option< (&syn::Lifetime, &syn::Type) > { +fn extract_lifetime_and_inner_ty( + args: &syn::punctuated::Punctuated, +) -> Option<(&syn::Lifetime, &syn::Type)> { if args.len() != 2 { return None; } - let lifetime = match args[ 0 ] { - syn::GenericArgument::Lifetime( ref lifetime ) => lifetime, - _ => return None + let lifetime = match args[0] { + syn::GenericArgument::Lifetime(ref lifetime) => lifetime, + _ => return None, }; - let ty = match args[ 1 ] { - syn::GenericArgument::Type( ref ty ) => ty, - _ => return None + let ty = match args[1] { + syn::GenericArgument::Type(ref ty) => ty, + _ => return None, }; - Some( (lifetime, ty) ) + Some((lifetime, ty)) } -fn extract_slice_inner_ty( ty: &syn::Type ) -> Option< &syn::Type > { +fn extract_slice_inner_ty(ty: &syn::Type) -> Option<&syn::Type> { match *ty { - syn::Type::Slice( syn::TypeSlice { ref elem, .. } ) => { - Some( &*elem ) - }, - _ => None + syn::Type::Slice(syn::TypeSlice { ref elem, .. }) => Some(&*elem), + _ => None, } } -fn is_bare_ty( ty: &syn::Type, name: &str ) -> bool { +fn is_bare_ty(ty: &syn::Type, name: &str) -> bool { match *ty { - syn::Type::Path( syn::TypePath { path: syn::Path { leading_colon: None, ref segments }, qself: None } ) if segments.len() == 1 => { - segments[ 0 ].ident == name && segments[ 0 ].arguments.is_empty() - }, - _ => false + syn::Type::Path(syn::TypePath { + path: + syn::Path { + leading_colon: None, + ref segments, + }, + qself: None, + }) if segments.len() == 1 => segments[0].ident == name && segments[0].arguments.is_empty(), + _ => false, } } -fn extract_option_inner_ty( ty: &syn::Type ) -> Option< &syn::Type > { +fn extract_option_inner_ty(ty: &syn::Type) -> Option<&syn::Type> { match *ty { - syn::Type::Path( syn::TypePath { path: syn::Path { leading_colon: None, ref segments }, qself: None } ) - if segments.len() == 1 && segments[ 0 ].ident == "Option" => - { - match segments[ 0 ].arguments { - syn::PathArguments::AngleBracketed( syn::AngleBracketedGenericArguments { colon2_token: None, ref args, .. } ) if args.len() == 1 => { - match args[ 0 ] { - syn::GenericArgument::Type( ref ty ) => Some( ty ), - _ => None - } + syn::Type::Path(syn::TypePath { + path: + syn::Path { + leading_colon: None, + ref segments, }, - _ => None - } + qself: None, + }) if segments.len() == 1 && segments[0].ident == "Option" => match segments[0].arguments { + syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments { + colon2_token: None, + ref args, + .. + }) if args.len() == 1 => match args[0] { + syn::GenericArgument::Type(ref ty) => Some(ty), + _ => None, + }, + _ => None, }, - _ => None + _ => None, } } -fn parse_ty( ty: &syn::Type ) -> Ty { - parse_special_ty( ty ).unwrap_or_else( || Ty::Ty( ty.clone() ) ) +fn parse_ty(ty: &syn::Type) -> Ty { + parse_special_ty(ty).unwrap_or_else(|| Ty::Ty(ty.clone())) } -fn parse_special_ty( ty: &syn::Type ) -> Option< Ty > { - if let Some( ty ) = parse_primitive_ty( ty ) { - return Some( Ty::Primitive( ty ) ); +fn parse_special_ty(ty: &syn::Type) -> Option { + if let Some(ty) = parse_primitive_ty(ty) { + return Some(Ty::Primitive(ty)); } match *ty { - syn::Type::Path( syn::TypePath { path: syn::Path { leading_colon: None, ref segments }, qself: None } ) if segments.len() == 1 => { - let name = &segments[ 0 ].ident; - match segments[ 0 ].arguments { + syn::Type::Path(syn::TypePath { + path: + syn::Path { + leading_colon: None, + ref segments, + }, + qself: None, + }) if segments.len() == 1 => { + let name = &segments[0].ident; + match segments[0].arguments { syn::PathArguments::None => { if name == "String" { - Some( Ty::String ) + Some(Ty::String) } else { None } - }, - syn::PathArguments::AngleBracketed( syn::AngleBracketedGenericArguments { colon2_token: None, ref args, .. } ) => { + } + syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments { + colon2_token: None, + ref args, + .. + }) => { if name == "Vec" { - Some( Ty::Vec( extract_inner_ty( args )?.clone() ) ) + Some(Ty::Vec(extract_inner_ty(args)?.clone())) } else if name == "HashSet" { - Some( Ty::HashSet( extract_inner_ty( args )?.clone() ) ) + Some(Ty::HashSet(extract_inner_ty(args)?.clone())) } else if name == "BTreeSet" { - Some( Ty::BTreeSet( extract_inner_ty( args )?.clone() ) ) + Some(Ty::BTreeSet(extract_inner_ty(args)?.clone())) } else if name == "Cow" { - let (lifetime, ty) = extract_lifetime_and_inner_ty( args )?; - if let Some( inner_ty ) = extract_slice_inner_ty( ty ) { - Some( Ty::CowSlice( lifetime.clone(), inner_ty.clone() ) ) - } else if is_bare_ty( ty, "str" ) { - Some( Ty::CowStr( lifetime.clone() ) ) + let (lifetime, ty) = extract_lifetime_and_inner_ty(args)?; + if let Some(inner_ty) = extract_slice_inner_ty(ty) { + Some(Ty::CowSlice(lifetime.clone(), inner_ty.clone())) + } else if is_bare_ty(ty, "str") { + Some(Ty::CowStr(lifetime.clone())) } else { match *ty { - syn::Type::Path( syn::TypePath { path: syn::Path { leading_colon: None, ref segments }, qself: None } ) if segments.len() == 1 => { - let inner_name = &segments[ 0 ].ident; - match segments[ 0 ].arguments { - syn::PathArguments::AngleBracketed( syn::AngleBracketedGenericArguments { colon2_token: None, ref args, .. } ) => { + syn::Type::Path(syn::TypePath { + path: + syn::Path { + leading_colon: None, + ref segments, + }, + qself: None, + }) if segments.len() == 1 => { + let inner_name = &segments[0].ident; + match segments[0].arguments { + syn::PathArguments::AngleBracketed( + syn::AngleBracketedGenericArguments { + colon2_token: None, + ref args, + .. + }, + ) => { if inner_name == "HashSet" { - Some( Ty::CowHashSet( lifetime.clone(), extract_inner_ty( args )?.clone() ) ) + Some(Ty::CowHashSet( + lifetime.clone(), + extract_inner_ty(args)?.clone(), + )) } else if inner_name == "BTreeSet" { - Some( Ty::CowBTreeSet( lifetime.clone(), extract_inner_ty( args )?.clone() ) ) + Some(Ty::CowBTreeSet( + lifetime.clone(), + extract_inner_ty(args)?.clone(), + )) } else if inner_name == "HashMap" { - let (key_ty, value_ty) = extract_inner_ty_2( args )?; - Some( Ty::CowHashMap( lifetime.clone(), key_ty.clone(), value_ty.clone() ) ) + let (key_ty, value_ty) = extract_inner_ty_2(args)?; + Some(Ty::CowHashMap( + lifetime.clone(), + key_ty.clone(), + value_ty.clone(), + )) } else if inner_name == "BTreeMap" { - let (key_ty, value_ty) = extract_inner_ty_2( args )?; - Some( Ty::CowBTreeMap( lifetime.clone(), key_ty.clone(), value_ty.clone() ) ) + let (key_ty, value_ty) = extract_inner_ty_2(args)?; + Some(Ty::CowBTreeMap( + lifetime.clone(), + key_ty.clone(), + value_ty.clone(), + )) } else { None } - }, - _ => None + } + _ => None, } - }, - _ => None + } + _ => None, } } } else if name == "HashMap" { - let (key_ty, value_ty) = extract_inner_ty_2( args )?; - Some( Ty::HashMap( key_ty.clone(), value_ty.clone() ) ) + let (key_ty, value_ty) = extract_inner_ty_2(args)?; + Some(Ty::HashMap(key_ty.clone(), value_ty.clone())) } else if name == "BTreeMap" { - let (key_ty, value_ty) = extract_inner_ty_2( args )?; - Some( Ty::BTreeMap( key_ty.clone(), value_ty.clone() ) ) + let (key_ty, value_ty) = extract_inner_ty_2(args)?; + Some(Ty::BTreeMap(key_ty.clone(), value_ty.clone())) } else { None } - }, - _ => None + } + _ => None, } - }, - syn::Type::Array( syn::TypeArray { + } + syn::Type::Array(syn::TypeArray { ref elem, - len: syn::Expr::Lit( syn::ExprLit { - ref attrs, - lit: syn::Lit::Int( ref literal ) - }), + len: + syn::Expr::Lit(syn::ExprLit { + ref attrs, + lit: syn::Lit::Int(ref literal), + }), .. }) if attrs.is_empty() => { - if let Ok( length ) = literal.base10_parse::< u32 >() { - Some( Ty::Array( (**elem).clone(), length ) ) + if let Ok(length) = literal.base10_parse::() { + Some(Ty::Array((**elem).clone(), length)) } else { None } - }, - syn::Type::Reference( syn::TypeReference { - lifetime: Some( ref lifetime ), + } + syn::Type::Reference(syn::TypeReference { + lifetime: Some(ref lifetime), mutability: None, ref elem, .. }) => { - if is_bare_ty( &*elem, "str" ) { - Some( Ty::RefStr( lifetime.clone() ) ) - } else if let Some( inner_ty ) = extract_slice_inner_ty( &*elem ) { - if is_bare_ty( inner_ty, "u8" ) { - Some( Ty::RefSliceU8( lifetime.clone() ) ) + if is_bare_ty(&*elem, "str") { + Some(Ty::RefStr(lifetime.clone())) + } else if let Some(inner_ty) = extract_slice_inner_ty(&*elem) { + if is_bare_ty(inner_ty, "u8") { + Some(Ty::RefSliceU8(lifetime.clone())) } else { - Some( Ty::RefSlice( lifetime.clone(), inner_ty.clone() ) ) + Some(Ty::RefSlice(lifetime.clone(), inner_ty.clone())) } } else { None } - }, - _ => None + } + _ => None, } } -fn get_fields< 'a, I: IntoIterator< Item = &'a syn::Field > + 'a >( fields: I ) -> Result< Vec< Field< 'a > >, syn::Error > { +fn get_fields<'a, I: IntoIterator + 'a>( + fields: I, +) -> Result>, syn::Error> { let mut length_until_eof_seen = false; let iter = fields.into_iter() .enumerate() @@ -1307,7 +1405,7 @@ fn get_fields< 'a, I: IntoIterator< Item = &'a syn::Field > + 'a >( fields: I ) iter.collect() } -fn default_on_eof_body( body: TokenStream ) -> TokenStream { +fn default_on_eof_body(body: TokenStream) -> TokenStream { quote! { match #body { Ok( value ) => value, @@ -1317,7 +1415,7 @@ fn default_on_eof_body( body: TokenStream ) -> TokenStream { } } -fn read_field_body( field: &Field ) -> TokenStream { +fn read_field_body(field: &Field) -> TokenStream { if field.skip { return quote! { std::default::Default::default() @@ -1325,10 +1423,10 @@ fn read_field_body( field: &Field ) -> TokenStream { } let read_length_body = match field.length { - Some( LengthKind::Expr( ref length ) ) => Some( quote! { ((#length) as usize) } ), - Some( LengthKind::UntilEndOfFile ) => None, + Some(LengthKind::Expr(ref length)) => Some(quote! { ((#length) as usize) }), + Some(LengthKind::UntilEndOfFile) => None, None => { - let read_length_fn = match field.length_type.unwrap_or( DEFAULT_LENGTH_TYPE ) { + let read_length_fn = match field.length_type.unwrap_or(DEFAULT_LENGTH_TYPE) { BasicType::U7 => quote! { read_length_u7 }, BasicType::U8 => quote! { read_length_u8 }, BasicType::U16 => quote! { read_length_u16 }, @@ -1342,15 +1440,15 @@ fn read_field_body( field: &Field ) -> TokenStream { }; if field.default_on_eof { - Some( default_on_eof_body( body ) ) + Some(default_on_eof_body(body)) } else { - Some( quote! { #body? } ) + Some(quote! { #body? }) } } }; let read_string = || { - if let Some( ref read_length_body ) = read_length_body { + if let Some(ref read_length_body) = read_length_body { quote! {{ let _length_ = #read_length_body; _reader_.read_vec( _length_ ).and_then( speedy::private::vec_to_string ) @@ -1363,7 +1461,7 @@ fn read_field_body( field: &Field ) -> TokenStream { }; let read_vec = || { - if let Some( ref read_length_body ) = read_length_body { + if let Some(ref read_length_body) = read_length_body { quote! {{ let _length_ = #read_length_body; _reader_.read_vec( _length_ ) @@ -1376,7 +1474,7 @@ fn read_field_body( field: &Field ) -> TokenStream { }; let read_cow_slice = || { - if let Some( ref read_length_body ) = read_length_body { + if let Some(ref read_length_body) = read_length_body { quote! {{ let _length_ = #read_length_body; _reader_.read_cow( _length_ ) @@ -1389,7 +1487,7 @@ fn read_field_body( field: &Field ) -> TokenStream { }; let read_cow_str = || { - if let Some( ref read_length_body ) = read_length_body { + if let Some(ref read_length_body) = read_length_body { quote! {{ let _length_ = #read_length_body; _reader_.read_cow( _length_ ).and_then( speedy::private::cow_bytes_to_cow_str ) @@ -1402,7 +1500,7 @@ fn read_field_body( field: &Field ) -> TokenStream { }; let read_collection = || { - if let Some( ref read_length_body ) = read_length_body { + if let Some(ref read_length_body) = read_length_body { quote! {{ let _length_ = #read_length_body; _reader_.read_collection( _length_ ) @@ -1415,7 +1513,7 @@ fn read_field_body( field: &Field ) -> TokenStream { }; let read_key_value_collection = || { - if let Some( ref read_length_body ) = read_length_body { + if let Some(ref read_length_body) = read_length_body { quote! {{ let _length_ = #read_length_body; _reader_.read_key_value_collection( _length_ ) @@ -1428,7 +1526,7 @@ fn read_field_body( field: &Field ) -> TokenStream { }; let read_cow_collection = || { - if let Some( ref read_length_body ) = read_length_body { + if let Some(ref read_length_body) = read_length_body { quote! {{ let _length_ = #read_length_body; _reader_.read_collection( _length_ ).map( std::borrow::Cow::Owned ) @@ -1441,7 +1539,7 @@ fn read_field_body( field: &Field ) -> TokenStream { }; let read_cow_key_value_collection = || { - if let Some( ref read_length_body ) = read_length_body { + if let Some(ref read_length_body) = read_length_body { quote! {{ let _length_ = #read_length_body; _reader_.read_key_value_collection( _length_ ).map( std::borrow::Cow::Owned ) @@ -1454,7 +1552,7 @@ fn read_field_body( field: &Field ) -> TokenStream { }; let read_ref_slice_u8 = || { - if let Some( ref read_length_body ) = read_length_body { + if let Some(ref read_length_body) = read_length_body { quote! {{ let _length_ = #read_length_body; _reader_.read_bytes_borrowed( _length_ ).ok_or_else( speedy::private::error_unsized ).and_then( |error| error ) @@ -1467,7 +1565,7 @@ fn read_field_body( field: &Field ) -> TokenStream { }; let read_ref_str = || { - if let Some( ref read_length_body ) = read_length_body { + if let Some(ref read_length_body) = read_length_body { quote! {{ let _length_ = #read_length_body; match _reader_.read_bytes_borrowed( _length_ ) { @@ -1488,7 +1586,7 @@ fn read_field_body( field: &Field ) -> TokenStream { let read_ref_slice = |inner_ty: &syn::Type| { let inner; - if let Some( ref read_length_body ) = read_length_body { + if let Some(ref read_length_body) = read_length_body { inner = quote! {{ let _length_ = #read_length_body; _length_.checked_mul( std::mem::size_of::< #inner_ty >() ) @@ -1521,10 +1619,12 @@ fn read_field_body( field: &Field ) -> TokenStream { let read_array = |length: u32| { // TODO: This is quite inefficient; for primitive types we can do better. - let readers = (0..length).map( |_| quote! { - match _reader_.read_value() { - Ok( value ) => value, - Err( error ) => return Err( error ) + let readers = (0..length).map(|_| { + quote! { + match _reader_.read_value() { + Ok( value ) => value, + Err( error ) => return Err( error ) + } } }); @@ -1539,7 +1639,7 @@ fn read_field_body( field: &Field ) -> TokenStream { }} }; - let read_option = |tokens: TokenStream| + let read_option = |tokens: TokenStream| { quote! {{ _reader_.read_u8().and_then( |_flag_| { if _flag_ != 0 { @@ -1548,39 +1648,35 @@ fn read_field_body( field: &Field ) -> TokenStream { Ok( None ) } }) - }}; + }} + }; let body = match field.ty.inner() { Ty::String => read_string(), - Ty::Vec( .. ) => read_vec(), - Ty::CowSlice( .. ) => read_cow_slice(), - Ty::CowStr( .. ) => read_cow_str(), - Ty::HashMap( .. ) | - Ty::BTreeMap( .. ) => read_key_value_collection(), - Ty::HashSet( .. ) | - Ty::BTreeSet( .. ) => read_collection(), - Ty::CowHashMap( .. ) | - Ty::CowBTreeMap( .. ) => read_cow_key_value_collection(), - Ty::CowHashSet( .. ) | - Ty::CowBTreeSet( .. ) => read_cow_collection(), - Ty::RefSliceU8( .. ) => read_ref_slice_u8(), - Ty::RefSlice( _, inner_ty ) => read_ref_slice( inner_ty ), - Ty::RefStr( .. ) => read_ref_str(), - Ty::Array( _, length ) => read_array( *length ), - Ty::Primitive( .. ) if field.varint => read_u64_varint(), - Ty::Primitive( .. ) | - Ty::Ty( .. ) => { - assert!( field.length.is_none() ); + Ty::Vec(..) => read_vec(), + Ty::CowSlice(..) => read_cow_slice(), + Ty::CowStr(..) => read_cow_str(), + Ty::HashMap(..) | Ty::BTreeMap(..) => read_key_value_collection(), + Ty::HashSet(..) | Ty::BTreeSet(..) => read_collection(), + Ty::CowHashMap(..) | Ty::CowBTreeMap(..) => read_cow_key_value_collection(), + Ty::CowHashSet(..) | Ty::CowBTreeSet(..) => read_cow_collection(), + Ty::RefSliceU8(..) => read_ref_slice_u8(), + Ty::RefSlice(_, inner_ty) => read_ref_slice(inner_ty), + Ty::RefStr(..) => read_ref_str(), + Ty::Array(_, length) => read_array(*length), + Ty::Primitive(..) if field.varint => read_u64_varint(), + Ty::Primitive(..) | Ty::Ty(..) => { + assert!(field.length.is_none()); quote! { _reader_.read_value() } } }; let body = match field.ty { - Opt::Plain( _ ) => body, - Opt::Option( _ ) => read_option( body ) + Opt::Plain(_) => body, + Opt::Option(_) => read_option(body), }; - let body = if let Some( ref constant_prefix ) = field.constant_prefix { + let body = if let Some(ref constant_prefix) = field.constant_prefix { quote! {{ speedy::private::read_constant( _reader_, #constant_prefix ).and_then( |_| #body ) }} @@ -1589,26 +1685,29 @@ fn read_field_body( field: &Field ) -> TokenStream { }; if field.default_on_eof { - default_on_eof_body( body ) + default_on_eof_body(body) } else { quote! { #body? } } } -fn readable_body< 'a >( types: &mut Vec< syn::Type >, st: &Struct< 'a > ) -> (TokenStream, TokenStream, TokenStream) { +fn readable_body<'a>( + types: &mut Vec, + st: &Struct<'a>, +) -> (TokenStream, TokenStream, TokenStream) { let mut field_names = Vec::new(); let mut field_readers = Vec::new(); let mut minimum_bytes_needed = Vec::new(); for field in &st.fields { - let read_value = read_field_body( field ); + let read_value = read_field_body(field); let name = field.var_name(); let raw_ty = field.raw_ty; - field_readers.push( quote! { let #name: #raw_ty = #read_value; } ); - field_names.push( name ); - types.extend( field.bound_types() ); + field_readers.push(quote! { let #name: #raw_ty = #read_value; }); + field_names.push(name); + types.extend(field.bound_types()); - if let Some( minimum_bytes ) = get_minimum_bytes( &field ) { - minimum_bytes_needed.push( minimum_bytes ); + if let Some(minimum_bytes) = get_minimum_bytes(&field) { + minimum_bytes_needed.push(minimum_bytes); } } @@ -1617,68 +1716,73 @@ fn readable_body< 'a >( types: &mut Vec< syn::Type >, st: &Struct< 'a > ) -> (To let initializer = match st.kind { StructKind::Unit => initializer, StructKind::Unnamed => quote! { ( #initializer ) }, - StructKind::Named => quote! { { #initializer } } + StructKind::Named => quote! { { #initializer } }, }; - let minimum_bytes_needed = sum( minimum_bytes_needed ); + let minimum_bytes_needed = sum(minimum_bytes_needed); (body, initializer, minimum_bytes_needed) } -fn write_field_body( field: &Field ) -> TokenStream { +fn write_field_body(field: &Field) -> TokenStream { let name = field.var_name(); let write_length_body = match field.length { - Some( LengthKind::Expr( ref length ) ) => { - let field_name = format!( "{}", name ); + Some(LengthKind::Expr(ref length)) => { + let field_name = format!("{}", name); quote! { if !speedy::private::are_lengths_the_same( #name.len(), #length ) { return Err( speedy::private::error_length_is_not_the_same_as_length_attribute( #field_name ) ); } } - }, - Some( LengthKind::UntilEndOfFile ) => quote! {}, + } + Some(LengthKind::UntilEndOfFile) => quote! {}, None => { - let write_length_fn = match field.length_type.unwrap_or( DEFAULT_LENGTH_TYPE ) { + let write_length_fn = match field.length_type.unwrap_or(DEFAULT_LENGTH_TYPE) { BasicType::U7 => quote! { write_length_u7 }, BasicType::U8 => quote! { write_length_u8 }, BasicType::U16 => quote! { write_length_u16 }, BasicType::U32 => quote! { write_length_u32 }, BasicType::U64 => quote! { write_length_u64 }, - BasicType::VarInt64 => quote! { write_length_u64_varint } + BasicType::VarInt64 => quote! { write_length_u64_varint }, }; quote! { speedy::private::#write_length_fn( #name.len(), _writer_ )?; } } }; - let write_str = || + let write_str = || { quote! {{ #write_length_body _writer_.write_slice( #name.as_bytes() )?; - }}; + }} + }; - let write_slice = || + let write_slice = || { quote! {{ #write_length_body _writer_.write_slice( &#name )?; - }}; + }} + }; - let write_collection = || + let write_collection = || { quote! {{ #write_length_body _writer_.write_collection( #name.iter() )?; - }}; + }} + }; - let write_array = || + let write_array = || { quote! {{ _writer_.write_slice( &#name[..] )?; - }}; + }} + }; - let write_u64_varint = || + let write_u64_varint = || { quote! {{ _writer_.write_u64_varint( *#name )?; - }}; + }} + }; - let write_option = |tokens: TokenStream| + let write_option = |tokens: TokenStream| { quote! {{ if let Some( ref #name ) = #name { _writer_.write_u8( 1 )?; @@ -1686,41 +1790,34 @@ fn write_field_body( field: &Field ) -> TokenStream { } else { _writer_.write_u8( 0 )?; } - }}; + }} + }; let body = match field.ty.inner() { - Ty::String | - Ty::CowStr( .. ) | - Ty::RefStr( .. ) - => write_str(), - Ty::Vec( .. ) | - Ty::CowSlice( .. ) | - Ty::RefSliceU8( .. ) | - Ty::RefSlice( .. ) - => write_slice(), - Ty::HashMap( .. ) | - Ty::HashSet( .. ) | - Ty::BTreeMap( .. ) | - Ty::BTreeSet( .. ) | - Ty::CowHashMap( .. ) | - Ty::CowHashSet( .. ) | - Ty::CowBTreeMap( .. ) | - Ty::CowBTreeSet( .. ) => write_collection(), - Ty::Array( .. ) => write_array(), - Ty::Primitive( .. ) if field.varint => write_u64_varint(), - Ty::Primitive( .. ) | - Ty::Ty( .. ) => { - assert!( field.length.is_none() ); + Ty::String | Ty::CowStr(..) | Ty::RefStr(..) => write_str(), + Ty::Vec(..) | Ty::CowSlice(..) | Ty::RefSliceU8(..) | Ty::RefSlice(..) => write_slice(), + Ty::HashMap(..) + | Ty::HashSet(..) + | Ty::BTreeMap(..) + | Ty::BTreeSet(..) + | Ty::CowHashMap(..) + | Ty::CowHashSet(..) + | Ty::CowBTreeMap(..) + | Ty::CowBTreeSet(..) => write_collection(), + Ty::Array(..) => write_array(), + Ty::Primitive(..) if field.varint => write_u64_varint(), + Ty::Primitive(..) | Ty::Ty(..) => { + assert!(field.length.is_none()); quote! { _writer_.write_value( #name )?; } } }; let body = match field.ty { - Opt::Plain( _ ) => body, - Opt::Option( _ ) => write_option( body ) + Opt::Plain(_) => body, + Opt::Option(_) => write_option(body), }; - let body = if let Some( ref constant_prefix ) = field.constant_prefix { + let body = if let Some(ref constant_prefix) = field.constant_prefix { quote! {{ _writer_.write_slice( #constant_prefix )?; #body @@ -1732,7 +1829,7 @@ fn write_field_body( field: &Field ) -> TokenStream { body } -fn writable_body< 'a >( types: &mut Vec< syn::Type >, st: &Struct< 'a > ) -> (TokenStream, TokenStream) { +fn writable_body<'a>(types: &mut Vec, st: &Struct<'a>) -> (TokenStream, TokenStream) { let mut field_names = Vec::new(); let mut field_writers = Vec::new(); for field in &st.fields { @@ -1740,11 +1837,11 @@ fn writable_body< 'a >( types: &mut Vec< syn::Type >, st: &Struct< 'a > ) -> (To continue; } - let write_value = write_field_body( &field ); - types.extend( field.bound_types() ); + let write_value = write_field_body(&field); + types.extend(field.bound_types()); - field_names.push( field.var_name().clone() ); - field_writers.push( write_value ); + field_names.push(field.var_name().clone()); + field_writers.push(write_value); } let body = quote! { #(#field_writers)* }; @@ -1752,40 +1849,40 @@ fn writable_body< 'a >( types: &mut Vec< syn::Type >, st: &Struct< 'a > ) -> (To let initializer = match st.kind { StructKind::Unit => initializer, StructKind::Unnamed => quote! { ( #initializer ) }, - StructKind::Named => quote! { { #initializer } } + StructKind::Named => quote! { { #initializer } }, }; (body, initializer) } -struct Variant< 'a > { +struct Variant<'a> { tag_expr: TokenStream, ident: &'a syn::Ident, - structure: Struct< 'a > + structure: Struct<'a>, } -struct Enum< 'a > { +struct Enum<'a> { tag_type: BasicType, peek_tag: bool, - variants: Vec< Variant< 'a > > + variants: Vec>, } -impl< 'a > Enum< 'a > { +impl<'a> Enum<'a> { fn new( ident: &syn::Ident, attrs: &[syn::Attribute], - raw_variants: &'a syn::punctuated::Punctuated< syn::Variant, syn::token::Comma > - ) -> Result< Self, syn::Error > { - let attrs = parse_attributes::< EnumAttribute >( attrs )?; - let attrs = collect_enum_attributes( attrs )?; - let tag_type = attrs.tag_type.unwrap_or( DEFAULT_ENUM_TAG_TYPE ); + raw_variants: &'a syn::punctuated::Punctuated, + ) -> Result { + let attrs = parse_attributes::(attrs)?; + let attrs = collect_enum_attributes(attrs)?; + let tag_type = attrs.tag_type.unwrap_or(DEFAULT_ENUM_TAG_TYPE); let max = match tag_type { BasicType::U7 => 0b01111111 as u64, BasicType::U8 => std::u8::MAX as u64, BasicType::U16 => std::u16::MAX as u64, BasicType::U32 => std::u32::MAX as u64, BasicType::U64 => std::u64::MAX, - BasicType::VarInt64 => std::u64::MAX + BasicType::VarInt64 => std::u64::MAX, }; let mut previous_tag = None; @@ -1794,29 +1891,30 @@ impl< 'a > Enum< 'a > { for variant in raw_variants { let mut struct_attrs = Vec::new(); let mut variant_attrs = Vec::new(); - for attr in parse_attributes::< VariantOrStructAttribute >( &variant.attrs )? { + for attr in parse_attributes::(&variant.attrs)? { match attr { - VariantOrStructAttribute::Struct( attr ) => struct_attrs.push( attr ), - VariantOrStructAttribute::Variant( attr ) => variant_attrs.push( attr ) + VariantOrStructAttribute::Struct(attr) => struct_attrs.push(attr), + VariantOrStructAttribute::Variant(attr) => variant_attrs.push(attr), } } - let variant_attrs = collect_variant_attributes( variant_attrs )?; + let variant_attrs = collect_variant_attributes(variant_attrs)?; - let full_name = format!( "{}::{}", ident, variant.ident ); - let tag = if let Some( tag ) = variant_attrs.tag { + let full_name = format!("{}::{}", ident, variant.ident); + let tag = if let Some(tag) = variant_attrs.tag { if tag > max { - let message = format!( "Enum discriminant `{}` is too big!", full_name ); - return Err( syn::Error::new( variant.span(), message ) ); + let message = format!("Enum discriminant `{}` is too big!", full_name); + return Err(syn::Error::new(variant.span(), message)); } tag } else { match variant.discriminant { None => { - let tag = if let Some( previous_tag ) = previous_tag { + let tag = if let Some(previous_tag) = previous_tag { if previous_tag >= max { - let message = format!( "Enum discriminant `{}` is too big!", full_name ); - return Err( syn::Error::new( variant.span(), message ) ); + let message = + format!("Enum discriminant `{}` is too big!", full_name); + return Err(syn::Error::new(variant.span(), message)); } previous_tag + 1 @@ -1825,126 +1923,138 @@ impl< 'a > Enum< 'a > { }; tag - }, - Some( (_, syn::Expr::Lit( syn::ExprLit { lit: syn::Lit::Int( ref raw_value ), .. } )) ) => { - let tag = raw_value.base10_parse::< u64 >().map_err( |err| { - syn::Error::new( raw_value.span(), err ) - })?; + } + Some(( + _, + syn::Expr::Lit(syn::ExprLit { + lit: syn::Lit::Int(ref raw_value), + .. + }), + )) => { + let tag = raw_value + .base10_parse::() + .map_err(|err| syn::Error::new(raw_value.span(), err))?; if tag > max { - let message = format!( "Enum discriminant `{}` is too big!", full_name ); - return Err( syn::Error::new( raw_value.span(), message ) ); + let message = format!("Enum discriminant `{}` is too big!", full_name); + return Err(syn::Error::new(raw_value.span(), message)); } tag - }, + } Some((_, ref expr)) => { - let message = format!( "Enum discriminant `{}` is currently unsupported!", full_name ); - return Err( syn::Error::new( expr.span(), message ) ); + let message = format!( + "Enum discriminant `{}` is currently unsupported!", + full_name + ); + return Err(syn::Error::new(expr.span(), message)); } } }; - previous_tag = Some( tag ); - if let Some( other_full_name ) = tag_to_full_name.get( &tag ) { - let message = format!( "Two discriminants with the same value of '{}': `{}`, `{}`", tag, full_name, other_full_name ); - return Err( syn::Error::new( variant.span(), message ) ); + previous_tag = Some(tag); + if let Some(other_full_name) = tag_to_full_name.get(&tag) { + let message = format!( + "Two discriminants with the same value of '{}': `{}`, `{}`", + tag, full_name, other_full_name + ); + return Err(syn::Error::new(variant.span(), message)); } - tag_to_full_name.insert( tag, full_name ); + tag_to_full_name.insert(tag, full_name); let tag_expr = match tag_type { BasicType::U7 | BasicType::U8 => { let tag = tag as u8; quote! { #tag } - }, + } BasicType::U16 => { let tag = tag as u16; quote! { #tag } - }, + } BasicType::U32 => { let tag = tag as u32; quote! { #tag } - }, + } BasicType::U64 | BasicType::VarInt64 => { let tag = tag as u64; quote! { #tag } } }; - let structure = Struct::new( &variant.fields, struct_attrs )?; - variants.push( Variant { + let structure = Struct::new(&variant.fields, struct_attrs)?; + variants.push(Variant { tag_expr, ident: &variant.ident, - structure + structure, }); } - Ok( Enum { + Ok(Enum { tag_type, peek_tag: attrs.peek_tag, - variants + variants, }) } } -fn get_minimum_bytes( field: &Field ) -> Option< TokenStream > { +fn get_minimum_bytes(field: &Field) -> Option { if field.default_on_eof || field.length.is_some() || field.skip { None } else { let mut length = match field.ty { - Opt::Option( .. ) => { + Opt::Option(..) => { quote! { 1 } - }, - Opt::Plain( ref ty ) => { - match ty { - | Ty::String - | Ty::Vec( .. ) - | Ty::CowSlice( .. ) - | Ty::CowStr( .. ) - | Ty::HashMap( .. ) - | Ty::HashSet( .. ) - | Ty::BTreeMap( .. ) - | Ty::BTreeSet( .. ) - | Ty::CowHashMap( .. ) - | Ty::CowHashSet( .. ) - | Ty::CowBTreeMap( .. ) - | Ty::CowBTreeSet( .. ) - | Ty::RefSliceU8( .. ) - | Ty::RefSlice( .. ) - | Ty::RefStr( .. ) - => { - let size: usize = match field.length_type.unwrap_or( DEFAULT_LENGTH_TYPE ) { - BasicType::U7 | BasicType::U8 | BasicType::VarInt64 => 1, - BasicType::U16 => 2, - BasicType::U32 => 4, - BasicType::U64 => 8 - }; + } + Opt::Plain(ref ty) => match ty { + Ty::String + | Ty::Vec(..) + | Ty::CowSlice(..) + | Ty::CowStr(..) + | Ty::HashMap(..) + | Ty::HashSet(..) + | Ty::BTreeMap(..) + | Ty::BTreeSet(..) + | Ty::CowHashMap(..) + | Ty::CowHashSet(..) + | Ty::CowBTreeMap(..) + | Ty::CowBTreeSet(..) + | Ty::RefSliceU8(..) + | Ty::RefSlice(..) + | Ty::RefStr(..) => { + let size: usize = match field.length_type.unwrap_or(DEFAULT_LENGTH_TYPE) { + BasicType::U7 | BasicType::U8 | BasicType::VarInt64 => 1, + BasicType::U16 => 2, + BasicType::U32 => 4, + BasicType::U64 => 8, + }; - quote! { #size } - }, - | Ty::Array( ty, length ) => { - let length = *length as usize; - quote! { <#ty as speedy::Readable< 'a_, C_ >>::minimum_bytes_needed() * #length } - }, - | Ty::Primitive( .. ) if field.varint => quote! { 1 }, - | Ty::Primitive( .. ) - | Ty::Ty( .. ) => { - let raw_ty = &field.raw_ty; - quote! { <#raw_ty as speedy::Readable< 'a_, C_ >>::minimum_bytes_needed() } - } + quote! { #size } } - } + Ty::Array(ty, length) => { + let length = *length as usize; + quote! { <#ty as speedy::Readable< 'a_, C_ >>::minimum_bytes_needed() * #length } + } + Ty::Primitive(..) if field.varint => quote! { 1 }, + Ty::Primitive(..) | Ty::Ty(..) => { + let raw_ty = &field.raw_ty; + quote! { <#raw_ty as speedy::Readable< 'a_, C_ >>::minimum_bytes_needed() } + } + }, }; - if let Some( ref constant_prefix ) = field.constant_prefix { + if let Some(ref constant_prefix) = field.constant_prefix { let extra_length = constant_prefix.value().len(); length = quote! { #length + #extra_length }; } - Some( length ) + Some(length) } } -fn sum< I >( values: I ) -> TokenStream where I: IntoIterator< Item = TokenStream >, ::IntoIter: ExactSizeIterator { +fn sum(values: I) -> TokenStream +where + I: IntoIterator, + ::IntoIter: ExactSizeIterator, +{ let iter = values.into_iter(); if iter.len() == 0 { quote! { 0 } @@ -1957,7 +2067,11 @@ fn sum< I >( values: I ) -> TokenStream where I: IntoIterator< Item = TokenStrea } } -fn min< I >( values: I ) -> TokenStream where I: IntoIterator< Item = TokenStream >, ::IntoIter: ExactSizeIterator { +fn min(values: I) -> TokenStream +where + I: IntoIterator, + ::IntoIter: ExactSizeIterator, +{ let iter = values.into_iter(); if iter.len() == 0 { quote! { 0 } @@ -1970,7 +2084,7 @@ fn min< I >( values: I ) -> TokenStream where I: IntoIterator< Item = TokenStrea } } -fn generate_is_primitive( fields: &[Field], is_writable: bool, check_order: bool ) -> TokenStream { +fn generate_is_primitive(fields: &[Field], is_writable: bool, check_order: bool) -> TokenStream { if fields.is_empty() { return quote! { true }; } @@ -1980,40 +2094,40 @@ fn generate_is_primitive( fields: &[Field], is_writable: bool, check_order: bool let mut fields_offsets = Vec::new(); for field in fields { if !is_primitive.is_empty() { - is_primitive.push( quote! { && }); - fields_size.push( quote! { + }); + is_primitive.push(quote! { && }); + fields_size.push(quote! { + }); } let ty = &field.raw_ty; if is_writable { - is_primitive.push( quote! { + is_primitive.push(quote! { <#ty as speedy::Writable< C_ >>::speedy_is_primitive() }); } else { - is_primitive.push( quote! { + is_primitive.push(quote! { <#ty as speedy::Readable< 'a_, C_ >>::speedy_is_primitive() }); } - fields_size.push( quote! { + fields_size.push(quote! { std::mem::size_of::< #ty >() }); let name = field.name(); - fields_offsets.push( quote! { + fields_offsets.push(quote! { speedy::private::offset_of!( Self, #name ) }); } - is_primitive.push( quote! { + is_primitive.push(quote! { && (#(#fields_size)*) == std::mem::size_of::< Self >() }); if check_order { - for window in fields_offsets.windows( 2 ) { + for window in fields_offsets.windows(2) { let a = &window[0]; let b = &window[1]; - is_primitive.push( quote! { + is_primitive.push(quote! { && #a <= #b }); } @@ -2024,20 +2138,25 @@ fn generate_is_primitive( fields: &[Field], is_writable: bool, check_order: bool } } -fn impl_readable( input: syn::DeriveInput ) -> Result< TokenStream, syn::Error > { +fn impl_readable(input: syn::DeriveInput) -> Result { let name = &input.ident; let mut types = Vec::new(); - let (reader_body, minimum_bytes_needed_body, impl_primitive, impl_zerocopyable) = match &input.data { - syn::Data::Struct( syn::DataStruct { ref fields, .. } ) => { - let attrs = parse_attributes::< StructAttribute >( &input.attrs )?; - let structure = Struct::new( fields, attrs )?; - let is_ty_packed = is_packed( &input.attrs ); - let is_ty_transparent = fields.len() == 1 && is_transparent( &input.attrs ); - let is_ty_c = is_c( &input.attrs ); - let is_ty_simple = structure.fields.iter().all( |field| field.is_simple() ); - let can_be_primitive = structure.fields.iter().all( |field| field.can_be_primitive() ); - let (body, initializer, minimum_bytes) = readable_body( &mut types, &structure ); + let (reader_body, minimum_bytes_needed_body, impl_primitive, impl_zerocopyable) = match &input + .data + { + syn::Data::Struct(syn::DataStruct { ref fields, .. }) => { + let attrs = parse_attributes::(&input.attrs)?; + let structure = Struct::new(fields, attrs)?; + let is_ty_packed = is_packed(&input.attrs); + let is_ty_transparent = fields.len() == 1 && is_transparent(&input.attrs); + let is_ty_c = is_c(&input.attrs); + let is_ty_simple = structure.fields.iter().all(|field| field.is_simple()); + let can_be_primitive = structure + .fields + .iter() + .all(|field| field.can_be_primitive()); + let (body, initializer, minimum_bytes) = readable_body(&mut types, &structure); let reader_body = quote! { #body Ok( #name #initializer ) @@ -2045,11 +2164,11 @@ fn impl_readable( input: syn::DeriveInput ) -> Result< TokenStream, syn::Error > let mut field_types = Vec::new(); for field in &structure.fields { - field_types.push( field.raw_ty.clone() ); + field_types.push(field.raw_ty.clone()); } let impl_primitive = if is_ty_transparent { - let field_ty = &structure.fields[ 0 ].raw_ty; + let field_ty = &structure.fields[0].raw_ty; quote! { #[inline(always)] fn speedy_is_primitive() -> bool { @@ -2070,14 +2189,20 @@ fn impl_readable( input: syn::DeriveInput ) -> Result< TokenStream, syn::Error > } } } - } else if can_be_primitive && (is_ty_packed || is_ty_c || is_ty_simple || (!uses_generics( &input ) && structure.fields.len() <= 4)) { - let is_primitive = generate_is_primitive( &structure.fields, false, !is_ty_packed && !is_ty_c ); + } else if can_be_primitive + && (is_ty_packed + || is_ty_c + || is_ty_simple + || (!uses_generics(&input) && structure.fields.len() <= 4)) + { + let is_primitive = + generate_is_primitive(&structure.fields, false, !is_ty_packed && !is_ty_c); let mut body_flip_endianness = Vec::new(); for field in &structure.fields { let ty = &field.raw_ty; let name = field.name(); - body_flip_endianness.push( quote! { + body_flip_endianness.push(quote! { unsafe { <#ty as speedy::Readable< 'a_, C_ >>::speedy_flip_endianness( std::ptr::addr_of_mut!( (*itself).#name ) @@ -2122,7 +2247,13 @@ fn impl_readable( input: syn::DeriveInput ) -> Result< TokenStream, syn::Error > }; let impl_zerocopyable = if is_ty_packed || is_ty_transparent { - let (impl_params, ty_params, where_clause) = common_tokens( &input, &field_types, Trait::ZeroCopyable { is_packed: is_ty_packed } ); + let (impl_params, ty_params, where_clause) = common_tokens( + &input, + &field_types, + Trait::ZeroCopyable { + is_packed: is_ty_packed, + }, + ); quote! { unsafe impl< #impl_params T_ > speedy::private::ZeroCopyable< T_ > for #name #ty_params #where_clause {} } @@ -2130,18 +2261,24 @@ fn impl_readable( input: syn::DeriveInput ) -> Result< TokenStream, syn::Error > quote! {} }; - (reader_body, minimum_bytes, impl_primitive, impl_zerocopyable) - }, - syn::Data::Enum( syn::DataEnum { variants, .. } ) => { - let enumeration = Enum::new( &name, &input.attrs, &variants )?; - let mut variant_matches = Vec::with_capacity( variants.len() ); - let mut variant_minimum_sizes = Vec::with_capacity( variants.len() ); + ( + reader_body, + minimum_bytes, + impl_primitive, + impl_zerocopyable, + ) + } + syn::Data::Enum(syn::DataEnum { variants, .. }) => { + let enumeration = Enum::new(&name, &input.attrs, &variants)?; + let mut variant_matches = Vec::with_capacity(variants.len()); + let mut variant_minimum_sizes = Vec::with_capacity(variants.len()); for variant in enumeration.variants { let tag = variant.tag_expr; let unqualified_ident = &variant.ident; let variant_path = quote! { #name::#unqualified_ident }; - let (body, initializer, minimum_bytes) = readable_body( &mut types, &variant.structure ); - variant_matches.push( quote! { + let (body, initializer, minimum_bytes) = + readable_body(&mut types, &variant.structure); + variant_matches.push(quote! { #tag => { #body Ok( #variant_path #initializer ) @@ -2150,7 +2287,7 @@ fn impl_readable( input: syn::DeriveInput ) -> Result< TokenStream, syn::Error > if variant.structure.kind != StructKind::Unit { if variant.structure.is_guaranteed_non_recursive() { - variant_minimum_sizes.push( minimum_bytes ); + variant_minimum_sizes.push(minimum_bytes); } } } @@ -2187,23 +2324,22 @@ fn impl_readable( input: syn::DeriveInput ) -> Result< TokenStream, syn::Error > _ => Err( speedy::private::error_invalid_enum_variant() ) } }; - let minimum_bytes_needed_body = min( variant_minimum_sizes.into_iter() ); - let minimum_bytes_needed_body = - if !enumeration.peek_tag { - quote! { (#minimum_bytes_needed_body) + #tag_size } - } else { - quote! { std::cmp::max( #minimum_bytes_needed_body, #tag_size ) } - }; + let minimum_bytes_needed_body = min(variant_minimum_sizes.into_iter()); + let minimum_bytes_needed_body = if !enumeration.peek_tag { + quote! { (#minimum_bytes_needed_body) + #tag_size } + } else { + quote! { std::cmp::max( #minimum_bytes_needed_body, #tag_size ) } + }; (reader_body, minimum_bytes_needed_body, quote! {}, quote! {}) - }, - syn::Data::Union( syn::DataUnion { union_token, .. } ) => { + } + syn::Data::Union(syn::DataUnion { union_token, .. }) => { let message = "Unions are not supported!"; - return Err( syn::Error::new( union_token.span(), message ) ); + return Err(syn::Error::new(union_token.span(), message)); } }; - let (impl_params, ty_params, where_clause) = common_tokens( &input, &types, Trait::Readable ); + let (impl_params, ty_params, where_clause) = common_tokens(&input, &types, Trait::Readable); let output = quote! { impl< 'a_, #impl_params C_: speedy::Context > speedy::Readable< 'a_, C_ > for #name #ty_params #where_clause { #[inline] @@ -2222,81 +2358,96 @@ fn impl_readable( input: syn::DeriveInput ) -> Result< TokenStream, syn::Error > #impl_zerocopyable }; - Ok( output ) + Ok(output) } -fn assign_to_variables< 'a >( fields: impl IntoIterator< Item = &'a Field< 'a > >, is_packed: bool ) -> TokenStream { - let fields: Vec< _ > = fields.into_iter().filter(|field| !field.skip).map( |field| { - let var_name = field.var_name(); - let name = field.name(); +fn assign_to_variables<'a>( + fields: impl IntoIterator>, + is_packed: bool, +) -> TokenStream { + let fields: Vec<_> = fields + .into_iter() + .filter(|field| !field.skip) + .map(|field| { + let var_name = field.var_name(); + let name = field.name(); - if !is_packed { - quote! { - let #var_name = &self.#name; - } - } else { - quote! { - let #var_name = self.#name; - let #var_name = &#var_name; + if !is_packed { + quote! { + let #var_name = &self.#name; + } + } else { + quote! { + let #var_name = self.#name; + let #var_name = &#var_name; + } } - } - }).collect(); + }) + .collect(); quote! { #(#fields)* } } -fn impl_writable( input: syn::DeriveInput ) -> Result< TokenStream, syn::Error > { +fn impl_writable(input: syn::DeriveInput) -> Result { let name = &input.ident; let mut types = Vec::new(); let (writer_body, impl_primitive) = match input.data { - syn::Data::Struct( syn::DataStruct { ref fields, .. } ) => { - let attrs = parse_attributes::< StructAttribute >( &input.attrs )?; - let st = Struct::new( fields, attrs )?; - let is_ty_packed = is_packed( &input.attrs ); - let is_ty_transparent = fields.len() == 1 && is_transparent( &input.attrs ); - let is_ty_c = is_c( &input.attrs ); - let is_ty_simple = st.fields.iter().all( |field| field.is_simple() ); - let can_be_primitive = st.fields.iter().all( |field| field.can_be_primitive() ); - let assignments = assign_to_variables( &st.fields, is_ty_packed ); - let (body, _) = writable_body( &mut types, &st ); - - let impl_primitive = - if is_ty_transparent { - let field_ty = &st.fields[ 0 ].raw_ty; - quote! { - #[inline(always)] - fn speedy_is_primitive() -> bool { - <#field_ty as speedy::Writable< C_ >>::speedy_is_primitive() - } + syn::Data::Struct(syn::DataStruct { ref fields, .. }) => { + let attrs = parse_attributes::(&input.attrs)?; + let st = Struct::new(fields, attrs)?; + let is_ty_packed = is_packed(&input.attrs); + let is_ty_transparent = fields.len() == 1 && is_transparent(&input.attrs); + let is_ty_c = is_c(&input.attrs); + let is_ty_simple = st.fields.iter().all(|field| field.is_simple()); + let can_be_primitive = st.fields.iter().all(|field| field.can_be_primitive()); + let assignments = assign_to_variables(&st.fields, is_ty_packed); + let (body, _) = writable_body(&mut types, &st); - #[inline(always)] - unsafe fn speedy_slice_as_bytes( slice: &[Self] ) -> &[u8] where Self: Sized { - unsafe { - std::slice::from_raw_parts( slice.as_ptr() as *const u8, slice.len() * std::mem::size_of::< Self >() ) - } - } + let impl_primitive = if is_ty_transparent { + let field_ty = &st.fields[0].raw_ty; + quote! { + #[inline(always)] + fn speedy_is_primitive() -> bool { + <#field_ty as speedy::Writable< C_ >>::speedy_is_primitive() } - } else if can_be_primitive && (is_ty_transparent || is_ty_packed || is_ty_c || is_ty_simple || (!uses_generics( &input ) && st.fields.len() <= 4)) { - let is_primitive = generate_is_primitive( &st.fields, true, !is_ty_transparent && !is_ty_packed && !is_ty_c ); - quote! { - #[inline(always)] - fn speedy_is_primitive() -> bool { - #is_primitive + #[inline(always)] + unsafe fn speedy_slice_as_bytes( slice: &[Self] ) -> &[u8] where Self: Sized { + unsafe { + std::slice::from_raw_parts( slice.as_ptr() as *const u8, slice.len() * std::mem::size_of::< Self >() ) } + } + } + } else if can_be_primitive + && (is_ty_transparent + || is_ty_packed + || is_ty_c + || is_ty_simple + || (!uses_generics(&input) && st.fields.len() <= 4)) + { + let is_primitive = generate_is_primitive( + &st.fields, + true, + !is_ty_transparent && !is_ty_packed && !is_ty_c, + ); + quote! { + #[inline(always)] + fn speedy_is_primitive() -> bool { + #is_primitive + } - #[inline(always)] - unsafe fn speedy_slice_as_bytes( slice: &[Self] ) -> &[u8] where Self: Sized { - unsafe { - std::slice::from_raw_parts( slice.as_ptr() as *const u8, slice.len() * std::mem::size_of::< Self >() ) - } + #[inline(always)] + unsafe fn speedy_slice_as_bytes( slice: &[Self] ) -> &[u8] where Self: Sized { + unsafe { + std::slice::from_raw_parts( slice.as_ptr() as *const u8, slice.len() * std::mem::size_of::< Self >() ) } } - } else { - quote! {} - }; + } + } else { + quote! {} + }; let impl_body = quote! { #assignments @@ -2304,9 +2455,9 @@ fn impl_writable( input: syn::DeriveInput ) -> Result< TokenStream, syn::Error > }; (impl_body, impl_primitive) - }, - syn::Data::Enum( syn::DataEnum { ref variants, .. } ) => { - let enumeration = Enum::new( &name, &input.attrs, &variants )?; + } + syn::Data::Enum(syn::DataEnum { ref variants, .. }) => { + let enumeration = Enum::new(&name, &input.attrs, &variants)?; let tag_writer = match enumeration.tag_type { BasicType::U64 => quote! { write_u64 }, BasicType::U32 => quote! { write_u32 }, @@ -2316,18 +2467,19 @@ fn impl_writable( input: syn::DeriveInput ) -> Result< TokenStream, syn::Error > BasicType::VarInt64 => quote! { write_u64_varint }, }; - let variants: Result< Vec< _ >, syn::Error > = enumeration.variants.iter() - .map( |variant| { + let variants: Result, syn::Error> = enumeration + .variants + .iter() + .map(|variant| { let unqualified_ident = &variant.ident; let tag_expr = &variant.tag_expr; let variant_path = quote! { #name::#unqualified_ident }; - let (body, initializer) = writable_body( &mut types, &variant.structure ); - let write_tag = - if !enumeration.peek_tag { - quote! { _writer_.#tag_writer( #tag_expr )?; } - } else { - quote! {} - }; + let (body, initializer) = writable_body(&mut types, &variant.structure); + let write_tag = if !enumeration.peek_tag { + quote! { _writer_.#tag_writer( #tag_expr )?; } + } else { + quote! {} + }; let snippet = quote! { #variant_path #initializer => { @@ -2336,19 +2488,19 @@ fn impl_writable( input: syn::DeriveInput ) -> Result< TokenStream, syn::Error > } }; - Ok( snippet ) + Ok(snippet) }) .collect(); let variants = variants?; (quote! { match *self { #(#variants),* } }, quote! {}) - }, - syn::Data::Union( syn::DataUnion { union_token, .. } ) => { + } + syn::Data::Union(syn::DataUnion { union_token, .. }) => { let message = "Unions are not supported!"; - return Err( syn::Error::new( union_token.span(), message ) ); + return Err(syn::Error::new(union_token.span(), message)); } }; - let (impl_params, ty_params, where_clause) = common_tokens( &input, &types, Trait::Writable ); + let (impl_params, ty_params, where_clause) = common_tokens(&input, &types, Trait::Writable); let output = quote! { impl< #impl_params C_: speedy::Context > speedy::Writable< C_ > for #name #ty_params #where_clause { #[inline] @@ -2361,5 +2513,5 @@ fn impl_writable( input: syn::DeriveInput ) -> Result< TokenStream, syn::Error > } }; - Ok( output ) + Ok(output) } diff --git a/src/circular_buffer.rs b/src/circular_buffer.rs index e77c1e5..901e770 100644 --- a/src/circular_buffer.rs +++ b/src/circular_buffer.rs @@ -1,37 +1,40 @@ -use { - std::{ - ops::{ - Range - } - } -}; +use std::ops::Range; pub struct CircularBuffer { - buffer: Box< [u8] >, + buffer: Box<[u8]>, position: usize, - length: usize + length: usize, } #[inline(always)] -fn occupied( position: usize, length: usize, capacity: usize ) -> (Range< usize >, Option< Range< usize > >) { +fn occupied( + position: usize, + length: usize, + capacity: usize, +) -> (Range, Option>) { if position + length <= capacity { let a = position..position + length; - debug_assert_eq!( a.len(), length ); + debug_assert_eq!(a.len(), length); (a, None) } else { let a = position..capacity; let b = 0..length - a.len(); - debug_assert_eq!( a.len() + b.len(), length ); - (a, Some( b )) + debug_assert_eq!(a.len() + b.len(), length); + (a, Some(b)) } } -fn empty( position: usize, length: usize, capacity: usize, mut max: usize ) -> (Range< usize >, Option< Range< usize > >) { +fn empty( + position: usize, + length: usize, + capacity: usize, + mut max: usize, +) -> (Range, Option>) { if position == 0 { let mut a = length..capacity; - debug_assert_eq!( a.len(), capacity - length ); + debug_assert_eq!(a.len(), capacity - length); let chunk_length = a.len(); if max < chunk_length { @@ -43,7 +46,7 @@ fn empty( position: usize, length: usize, capacity: usize, mut max: usize ) -> ( let right_chunk_length = capacity - position; let left_chunk_length = length - right_chunk_length; let mut a = left_chunk_length..capacity - right_chunk_length; - debug_assert_eq!( a.len(), capacity - length ); + debug_assert_eq!(a.len(), capacity - length); let chunk_length = a.len(); if max < chunk_length { @@ -54,7 +57,7 @@ fn empty( position: usize, length: usize, capacity: usize, mut max: usize ) -> ( } else { let mut a = position + length..capacity; let mut b = 0..position; - debug_assert_eq!( a.len() + b.len(), capacity - length ); + debug_assert_eq!(a.len() + b.len(), capacity - length); let chunk_length = a.len(); if max <= chunk_length { @@ -68,140 +71,77 @@ fn empty( position: usize, length: usize, capacity: usize, mut max: usize ) -> ( b.end = b.start + max; } - (a, Some( b )) + (a, Some(b)) } } #[test] fn test_circular_index_occupied() { // Empty. - assert_eq!( - occupied( 0, 0, 10 ), - (0..0, None) - ); + assert_eq!(occupied(0, 0, 10), (0..0, None)); // Empty with position in the middle. - assert_eq!( - occupied( 5, 0, 10 ), - (5..5, None) - ); + assert_eq!(occupied(5, 0, 10), (5..5, None)); // Fully occupied. - assert_eq!( - occupied( 0, 10, 10 ), - (0..10, None) - ); + assert_eq!(occupied(0, 10, 10), (0..10, None)); // Occupied only in the left half. - assert_eq!( - occupied( 0, 5, 10 ), - (0..5, None) - ); + assert_eq!(occupied(0, 5, 10), (0..5, None)); // Occupied only in the right half. - assert_eq!( - occupied( 5, 5, 10 ), - (5..10, None) - ); + assert_eq!(occupied(5, 5, 10), (5..10, None)); // Occupied only in the middle. - assert_eq!( - occupied( 1, 8, 10 ), - (1..9, None) - ); + assert_eq!(occupied(1, 8, 10), (1..9, None)); // Fully occupied overflowing the end. - assert_eq!( - occupied( 5, 10, 10 ), - (5..10, Some(0..5)) - ); + assert_eq!(occupied(5, 10, 10), (5..10, Some(0..5))); } #[test] fn test_circular_index_empty() { // Empty. - assert_eq!( - empty( 0, 0, 10, !0 ), - (0..10, None) - ); + assert_eq!(empty(0, 0, 10, !0), (0..10, None)); // Empty (with limit). - assert_eq!( - empty( 0, 0, 10, 1 ), - (0..1, None) - ); + assert_eq!(empty(0, 0, 10, 1), (0..1, None)); // Empty with position in the middle. - assert_eq!( - empty( 5, 0, 10, !0 ), - (5..10, Some( 0..5 )) - ); + assert_eq!(empty(5, 0, 10, !0), (5..10, Some(0..5))); // Empty with position in the middle (with limit). - assert_eq!( - empty( 5, 0, 10, 1 ), - (5..6, None) - ); + assert_eq!(empty(5, 0, 10, 1), (5..6, None)); // Fully occupied. - assert_eq!( - empty( 0, 10, 10, !0 ), - (10..10, None) - ); + assert_eq!(empty(0, 10, 10, !0), (10..10, None)); // Fully occupied (with limit). - assert_eq!( - empty( 0, 10, 10, 1 ), - (10..10, None) - ); + assert_eq!(empty(0, 10, 10, 1), (10..10, None)); // Occupied only in the left half. - assert_eq!( - empty( 0, 5, 10, !0 ), - (5..10, None) - ); + assert_eq!(empty(0, 5, 10, !0), (5..10, None)); // Occupied only in the left half (with limit). - assert_eq!( - empty( 0, 5, 10, 1 ), - (5..6, None) - ); + assert_eq!(empty(0, 5, 10, 1), (5..6, None)); // Occupied only in the right half. - assert_eq!( - empty( 5, 5, 10, !0 ), - (0..5, None) - ); + assert_eq!(empty(5, 5, 10, !0), (0..5, None)); // Occupied only in the right half (with limit). - assert_eq!( - empty( 5, 5, 10, 1 ), - (0..1, None) - ); + assert_eq!(empty(5, 5, 10, 1), (0..1, None)); // Occupied only in the middle. - assert_eq!( - empty( 2, 6, 10, !0 ), - (8..10, Some( 0..2 )) - ); + assert_eq!(empty(2, 6, 10, !0), (8..10, Some(0..2))); // Occupied only in the middle (with limit which prevents a boundary cross). - assert_eq!( - empty( 2, 6, 10, 2 ), - (8..10, None ) - ); + assert_eq!(empty(2, 6, 10, 2), (8..10, None)); // Occupied only in the middle (with limit which doesn't prevent a boundary cross). - assert_eq!( - empty( 2, 6, 10, 3 ), - (8..10, Some( 0..1 )) - ); + assert_eq!(empty(2, 6, 10, 3), (8..10, Some(0..1))); // Fully occupied overflowing the end. - assert_eq!( - empty( 5, 10, 10, !0 ), - (5..5, None) - ); + assert_eq!(empty(5, 10, 10, !0), (5..5, None)); } impl CircularBuffer { @@ -210,50 +150,50 @@ impl CircularBuffer { CircularBuffer { buffer: Vec::new().into_boxed_slice(), position: 0, - length: 0 + length: 0, } } - pub fn with_capacity( capacity: usize ) -> Self { - let mut buffer = Vec::with_capacity( capacity ); + pub fn with_capacity(capacity: usize) -> Self { + let mut buffer = Vec::with_capacity(capacity); unsafe { - buffer.set_len( capacity ); - if cfg!( debug_assertions ) { - std::ptr::write_bytes( buffer.as_mut_ptr(), 0xFF, buffer.len() ); + buffer.set_len(capacity); + if cfg!(debug_assertions) { + std::ptr::write_bytes(buffer.as_mut_ptr(), 0xFF, buffer.len()); } } CircularBuffer { buffer: buffer.into_boxed_slice(), position: 0, - length: 0 + length: 0, } } #[cfg(test)] - pub fn is_empty( &self ) -> bool { + pub fn is_empty(&self) -> bool { self.length == 0 } #[inline(always)] - pub fn len( &self ) -> usize { + pub fn len(&self) -> usize { self.length } - pub fn capacity( &self ) -> usize { + pub fn capacity(&self) -> usize { self.buffer.len() } #[cfg(test)] - pub fn reserve_exact( &mut self, size: usize ) { - self.reserve_impl( size, true ) + pub fn reserve_exact(&mut self, size: usize) { + self.reserve_impl(size, true) } - pub fn reserve( &mut self, size: usize ) { - self.reserve_impl( size, false ) + pub fn reserve(&mut self, size: usize) { + self.reserve_impl(size, false) } - fn reserve_impl( &mut self, size: usize, is_exact: bool ) { + fn reserve_impl(&mut self, size: usize, is_exact: bool) { let mut new_capacity = self.length + size; if !is_exact && self.buffer.len() >= new_capacity { return; @@ -265,84 +205,88 @@ impl CircularBuffer { let mut new_buffer = Vec::new(); if !is_exact { - new_buffer.reserve( new_capacity ); + new_buffer.reserve(new_capacity); } else { - new_buffer.reserve_exact( new_capacity ); + new_buffer.reserve_exact(new_capacity); } new_capacity = new_buffer.capacity(); unsafe { - new_buffer.set_len( new_capacity ); + new_buffer.set_len(new_capacity); } - let (a, b) = occupied( self.position, self.length, self.buffer.len() ); - new_buffer[ 0..a.len() ].copy_from_slice( &self.buffer[ a.clone() ] ); + let (a, b) = occupied(self.position, self.length, self.buffer.len()); + new_buffer[0..a.len()].copy_from_slice(&self.buffer[a.clone()]); - if let Some( b ) = b { - new_buffer[ a.len()..self.length ].copy_from_slice( &self.buffer[ b ] ); + if let Some(b) = b { + new_buffer[a.len()..self.length].copy_from_slice(&self.buffer[b]); } self.buffer = new_buffer.into_boxed_slice(); self.position = 0; } - pub fn try_append_with< E >( &mut self, size: usize, callback: impl FnOnce( &mut [u8] ) -> Result< usize, E > ) -> Result< usize, E > { - self.reserve( size ); + pub fn try_append_with( + &mut self, + size: usize, + callback: impl FnOnce(&mut [u8]) -> Result, + ) -> Result { + self.reserve(size); - let (range, _) = empty( self.position, self.length, self.buffer.len(), size ); - let bytes_written = callback( &mut self.buffer[ range ] )?; + let (range, _) = empty(self.position, self.length, self.buffer.len(), size); + let bytes_written = callback(&mut self.buffer[range])?; self.length += bytes_written; - Ok( bytes_written ) + Ok(bytes_written) } #[inline(always)] - pub fn as_slices( &self ) -> (&[u8], Option< &[u8] >) { - let (a, b) = occupied( self.position, self.length, self.buffer.len() ); - debug_assert_eq!( a.start, self.position ); - (&self.buffer[ a ], b.map( |b| &self.buffer[ b ] )) + pub fn as_slices(&self) -> (&[u8], Option<&[u8]>) { + let (a, b) = occupied(self.position, self.length, self.buffer.len()); + debug_assert_eq!(a.start, self.position); + (&self.buffer[a], b.map(|b| &self.buffer[b])) } #[inline(always)] - pub fn as_slices_of_length( &self, length: usize ) -> (&[u8], Option< &[u8] >) { - assert!( length <= self.length ); + pub fn as_slices_of_length(&self, length: usize) -> (&[u8], Option<&[u8]>) { + assert!(length <= self.length); let (a, b) = self.as_slices(); if length <= a.len() { - (&a[ ..length ], None) + (&a[..length], None) } else { - (a, b.map( |b| &b[ ..length - a.len() ] )) + (a, b.map(|b| &b[..length - a.len()])) } } #[cfg(test)] - pub fn to_vec( &self ) -> Vec< u8 > { - let mut output = Vec::with_capacity( self.len() ); + pub fn to_vec(&self) -> Vec { + let mut output = Vec::with_capacity(self.len()); let (a, b) = self.as_slices(); - output.extend_from_slice( a ); + output.extend_from_slice(a); - if let Some( b ) = b { - output.extend_from_slice( b ); + if let Some(b) = b { + output.extend_from_slice(b); } output } #[cfg(test)] - pub fn extend_from_slice( &mut self, slice: &[u8] ) { - self.reserve( slice.len() ); - let (range_1, range_2) = empty( self.position, self.length, self.buffer.len(), slice.len() ); + pub fn extend_from_slice(&mut self, slice: &[u8]) { + self.reserve(slice.len()); + let (range_1, range_2) = empty(self.position, self.length, self.buffer.len(), slice.len()); - self.buffer[ range_1.clone() ].copy_from_slice( &slice[ ..range_1.len() ] ); - if let Some( range_2 ) = range_2 { - self.buffer[ range_2.clone() ].copy_from_slice( &slice[ range_1.len().. ] ); + self.buffer[range_1.clone()].copy_from_slice(&slice[..range_1.len()]); + if let Some(range_2) = range_2 { + self.buffer[range_2.clone()].copy_from_slice(&slice[range_1.len()..]); } self.length += slice.len(); } #[inline(always)] - pub fn consume( &mut self, length: usize ) { - assert!( length <= self.length ); + pub fn consume(&mut self, length: usize) { + assert!(length <= self.length); self.position = (self.position + length) % self.buffer.len(); self.length -= length; @@ -352,10 +296,10 @@ impl CircularBuffer { } #[inline(always)] - pub fn consume_into( &mut self, buffer: &mut [u8] ) { - let length = std::cmp::min( self.length, buffer.len() ); + pub fn consume_into(&mut self, buffer: &mut [u8]) { + let length = std::cmp::min(self.length, buffer.len()); if self.position + length < self.buffer.len() { - buffer[ ..length ].copy_from_slice( &self.buffer[ self.position..self.position + length ] ); + buffer[..length].copy_from_slice(&self.buffer[self.position..self.position + length]); self.position += length; self.length -= length; if self.length == 0 { @@ -365,115 +309,117 @@ impl CircularBuffer { return; } - self.consume_into_slow( buffer ) + self.consume_into_slow(buffer) } #[inline(never)] - fn consume_into_slow( &mut self, buffer: &mut [u8] ) { + fn consume_into_slow(&mut self, buffer: &mut [u8]) { if buffer.is_empty() { return; } - assert!( buffer.len() <= self.length ); - let (a, b) = self.as_slices_of_length( buffer.len() ); - buffer[ ..a.len() ].copy_from_slice( a ); + assert!(buffer.len() <= self.length); + let (a, b) = self.as_slices_of_length(buffer.len()); + buffer[..a.len()].copy_from_slice(a); - if let Some( b ) = b { - buffer[ a.len().. ].copy_from_slice( b ); + if let Some(b) = b { + buffer[a.len()..].copy_from_slice(b); } - self.consume( buffer.len() ); + self.consume(buffer.len()); } } #[test] fn test_circular_buffer_basic() { let mut buf = CircularBuffer::new(); - assert_eq!( buf.len(), 0 ); - assert_eq!( buf.capacity(), 0 ); - assert_eq!( buf.is_empty(), true ); - - buf.reserve_exact( 3 ); - assert_eq!( buf.len(), 0 ); - assert_eq!( buf.capacity(), 3 ); - assert_eq!( buf.is_empty(), true ); - - buf.extend_from_slice( &[1, 2] ); - assert_eq!( buf.len(), 2 ); - assert_eq!( buf.capacity(), 3 ); - assert_eq!( buf.is_empty(), false ); - assert_eq!( buf.as_slices(), (&[1, 2][..], None) ); - assert_eq!( buf.to_vec(), vec![1, 2] ); - assert_eq!( buf.as_slices_of_length(0), (&[][..], None) ); - assert_eq!( buf.as_slices_of_length(1), (&[1][..], None) ); - assert_eq!( buf.as_slices_of_length(2), (&[1, 2][..], None) ); - - buf.extend_from_slice( &[3] ); - assert_eq!( buf.len(), 3 ); - assert_eq!( buf.capacity(), 3 ); - assert_eq!( buf.as_slices(), (&[1, 2, 3][..], None) ); - assert_eq!( buf.to_vec(), vec![1, 2, 3] ); - assert_eq!( buf.as_slices_of_length(0), (&[][..], None) ); - assert_eq!( buf.as_slices_of_length(1), (&[1][..], None) ); - assert_eq!( buf.as_slices_of_length(2), (&[1, 2][..], None) ); - assert_eq!( buf.as_slices_of_length(3), (&[1, 2, 3][..], None) ); + assert_eq!(buf.len(), 0); + assert_eq!(buf.capacity(), 0); + assert_eq!(buf.is_empty(), true); + + buf.reserve_exact(3); + assert_eq!(buf.len(), 0); + assert_eq!(buf.capacity(), 3); + assert_eq!(buf.is_empty(), true); + + buf.extend_from_slice(&[1, 2]); + assert_eq!(buf.len(), 2); + assert_eq!(buf.capacity(), 3); + assert_eq!(buf.is_empty(), false); + assert_eq!(buf.as_slices(), (&[1, 2][..], None)); + assert_eq!(buf.to_vec(), vec![1, 2]); + assert_eq!(buf.as_slices_of_length(0), (&[][..], None)); + assert_eq!(buf.as_slices_of_length(1), (&[1][..], None)); + assert_eq!(buf.as_slices_of_length(2), (&[1, 2][..], None)); + + buf.extend_from_slice(&[3]); + assert_eq!(buf.len(), 3); + assert_eq!(buf.capacity(), 3); + assert_eq!(buf.as_slices(), (&[1, 2, 3][..], None)); + assert_eq!(buf.to_vec(), vec![1, 2, 3]); + assert_eq!(buf.as_slices_of_length(0), (&[][..], None)); + assert_eq!(buf.as_slices_of_length(1), (&[1][..], None)); + assert_eq!(buf.as_slices_of_length(2), (&[1, 2][..], None)); + assert_eq!(buf.as_slices_of_length(3), (&[1, 2, 3][..], None)); buf.consume(1); - assert_eq!( buf.len(), 2 ); - assert_eq!( buf.capacity(), 3 ); - assert_eq!( buf.as_slices(), (&[2, 3][..], None) ); - assert_eq!( buf.to_vec(), vec![2, 3] ); - - buf.extend_from_slice( &[4] ); - assert_eq!( buf.len(), 3 ); - assert_eq!( buf.capacity(), 3 ); - assert_eq!( buf.as_slices(), (&[2, 3][..], Some(&[4][..])) ); - assert_eq!( buf.to_vec(), vec![2, 3, 4] ); - assert_eq!( buf.as_slices_of_length(0), (&[][..], None) ); - assert_eq!( buf.as_slices_of_length(1), (&[2][..], None) ); - assert_eq!( buf.as_slices_of_length(2), (&[2, 3][..], None) ); - assert_eq!( buf.as_slices_of_length(3), (&[2, 3][..], Some(&[4][..])) ); - - buf.extend_from_slice( &[5] ); - assert_eq!( buf.len(), 4 ); - assert_eq!( buf.as_slices(), (&[2, 3, 4, 5][..], None) ); - assert_eq!( buf.to_vec(), vec![2, 3, 4, 5] ); + assert_eq!(buf.len(), 2); + assert_eq!(buf.capacity(), 3); + assert_eq!(buf.as_slices(), (&[2, 3][..], None)); + assert_eq!(buf.to_vec(), vec![2, 3]); + + buf.extend_from_slice(&[4]); + assert_eq!(buf.len(), 3); + assert_eq!(buf.capacity(), 3); + assert_eq!(buf.as_slices(), (&[2, 3][..], Some(&[4][..]))); + assert_eq!(buf.to_vec(), vec![2, 3, 4]); + assert_eq!(buf.as_slices_of_length(0), (&[][..], None)); + assert_eq!(buf.as_slices_of_length(1), (&[2][..], None)); + assert_eq!(buf.as_slices_of_length(2), (&[2, 3][..], None)); + assert_eq!(buf.as_slices_of_length(3), (&[2, 3][..], Some(&[4][..]))); + + buf.extend_from_slice(&[5]); + assert_eq!(buf.len(), 4); + assert_eq!(buf.as_slices(), (&[2, 3, 4, 5][..], None)); + assert_eq!(buf.to_vec(), vec![2, 3, 4, 5]); let tmp = &mut [0, 0, 0, 0]; - buf.consume_into( &mut tmp[..] ); - assert_eq!( tmp, &[2, 3, 4, 5] ); + buf.consume_into(&mut tmp[..]); + assert_eq!(tmp, &[2, 3, 4, 5]); } #[test] fn test_circular_buffer_partial_try_append_with() { let mut buf = CircularBuffer::new(); - buf.reserve_exact( 3 ); - buf.extend_from_slice( &[1, 2] ); - buf.consume( 1 ); - assert_eq!( buf.to_vec(), vec![2] ); - buf.try_append_with( 2, |chunk| { - assert_eq!( chunk.len(), 1 ); + buf.reserve_exact(3); + buf.extend_from_slice(&[1, 2]); + buf.consume(1); + assert_eq!(buf.to_vec(), vec![2]); + buf.try_append_with(2, |chunk| { + assert_eq!(chunk.len(), 1); chunk[0] = 3; - let result: Result< _, () > = Ok(1); + let result: Result<_, ()> = Ok(1); result - }).unwrap(); + }) + .unwrap(); - assert_eq!( buf.to_vec(), vec![2, 3] ); + assert_eq!(buf.to_vec(), vec![2, 3]); } #[test] fn test_circular_buffer_append_and_consume() { - let mut buf = CircularBuffer::with_capacity( 1024 ); + let mut buf = CircularBuffer::with_capacity(1024); for _ in 0..2 { - buf.try_append_with( 1, |output| { - output[ 0 ] = 0; - let result: Result< _, () > = Ok( output.len() ); + buf.try_append_with(1, |output| { + output[0] = 0; + let result: Result<_, ()> = Ok(output.len()); result - }).unwrap(); + }) + .unwrap(); let mut actual = [0xaa]; - buf.consume_into( &mut actual ); - assert_eq!( actual[0], 0 ); + buf.consume_into(&mut actual); + assert_eq!(actual[0], 0); } } diff --git a/src/context.rs b/src/context.rs index cd8ca54..2a78f59 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,15 +1,15 @@ use crate::endianness::Endianness; pub trait Context { - type Error: From< crate::Error > + crate::IsEof; - fn endianness( &self ) -> Endianness; + type Error: From + crate::IsEof; + fn endianness(&self) -> Endianness; } impl Context for Endianness { type Error = crate::Error; #[inline(always)] - fn endianness( &self ) -> Endianness { + fn endianness(&self) -> Endianness { *self } } @@ -24,7 +24,7 @@ impl Context for LittleEndian { type Error = crate::Error; #[inline(always)] - fn endianness( &self ) -> Endianness { + fn endianness(&self) -> Endianness { Endianness::LittleEndian } } @@ -33,7 +33,7 @@ impl Context for BigEndian { type Error = crate::Error; #[inline(always)] - fn endianness( &self ) -> Endianness { + fn endianness(&self) -> Endianness { Endianness::BigEndian } } @@ -42,6 +42,9 @@ pub trait DefaultContext { type Context; } -impl< T > DefaultContext for T where T: ?Sized { +impl DefaultContext for T +where + T: ?Sized, +{ type Context = LittleEndian; } diff --git a/src/endianness.rs b/src/endianness.rs index 59bab9d..27d9f43 100644 --- a/src/endianness.rs +++ b/src/endianness.rs @@ -1,43 +1,43 @@ #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] pub enum Endianness { LittleEndian, - BigEndian + BigEndian, } impl Endianness { - #[cfg( target_endian = "little" )] + #[cfg(target_endian = "little")] pub const NATIVE: Endianness = Endianness::LittleEndian; - #[cfg( target_endian = "big" )] + #[cfg(target_endian = "big")] pub const NATIVE: Endianness = Endianness::BigEndian; } impl Endianness { #[inline(always)] - pub fn conversion_necessary( self ) -> bool { + pub fn conversion_necessary(self) -> bool { self != Endianness::NATIVE } #[inline(always)] - pub fn swap_slice_u8( self, _: &mut [u8] ) {} + pub fn swap_slice_u8(self, _: &mut [u8]) {} #[inline(always)] - pub fn swap_slice_i8( self, _: &mut [i8] ) {} + pub fn swap_slice_i8(self, _: &mut [i8]) {} } macro_rules! emit_wrapper { ($type:ty, $reader:ident, $swapper:ident, $slice_swapper:ident) => { impl Endianness { #[inline] - pub fn $reader( self, slice: &[u8] ) -> $type { - assert!( slice.len() == core::mem::size_of::< $type >() ); + pub fn $reader(self, slice: &[u8]) -> $type { + assert!(slice.len() == core::mem::size_of::<$type>()); let mut value: $type = 0; unsafe { core::ptr::copy_nonoverlapping( slice.as_ptr(), &mut value as *mut $type as *mut u8, - core::mem::size_of::< $type >() + core::mem::size_of::<$type>(), ); } @@ -49,14 +49,14 @@ macro_rules! emit_wrapper { } #[inline] - pub fn $swapper( self, value: &mut $type ) { + pub fn $swapper(self, value: &mut $type) { if self.conversion_necessary() { *value = value.swap_bytes(); } } #[inline] - pub fn $slice_swapper( self, slice: &mut [$type] ) { + pub fn $slice_swapper(self, slice: &mut [$type]) { if self.conversion_necessary() { for value in slice { *value = value.swap_bytes(); @@ -64,62 +64,56 @@ macro_rules! emit_wrapper { } } } - } + }; } -emit_wrapper!( u16, read_u16, swap_u16, swap_slice_u16 ); -emit_wrapper!( u32, read_u32, swap_u32, swap_slice_u32 ); -emit_wrapper!( u64, read_u64, swap_u64, swap_slice_u64 ); -emit_wrapper!( u128, read_u128, swap_u128, swap_slice_u128 ); -emit_wrapper!( i16, read_i16, swap_i16, swap_slice_i16 ); -emit_wrapper!( i32, read_i32, swap_i32, swap_slice_i32 ); -emit_wrapper!( i64, read_i64, swap_i64, swap_slice_i64 ); -emit_wrapper!( i128, read_i128, swap_i128, swap_slice_i128 ); +emit_wrapper!(u16, read_u16, swap_u16, swap_slice_u16); +emit_wrapper!(u32, read_u32, swap_u32, swap_slice_u32); +emit_wrapper!(u64, read_u64, swap_u64, swap_slice_u64); +emit_wrapper!(u128, read_u128, swap_u128, swap_slice_u128); +emit_wrapper!(i16, read_i16, swap_i16, swap_slice_i16); +emit_wrapper!(i32, read_i32, swap_i32, swap_slice_i32); +emit_wrapper!(i64, read_i64, swap_i64, swap_slice_i64); +emit_wrapper!(i128, read_i128, swap_i128, swap_slice_i128); impl Endianness { #[inline] - pub fn read_f32( self, slice: &[u8] ) -> f32 { - f32::from_bits( self.read_u32( slice ) ) + pub fn read_f32(self, slice: &[u8]) -> f32 { + f32::from_bits(self.read_u32(slice)) } #[inline] - pub fn read_f64( self, slice: &[u8] ) -> f64 { - f64::from_bits( self.read_u64( slice ) ) + pub fn read_f64(self, slice: &[u8]) -> f64 { + f64::from_bits(self.read_u64(slice)) } #[inline] - pub fn swap_f32( self, value: &mut f32 ) { - let value = unsafe { - &mut *(value as *mut f32 as *mut u32) - }; + pub fn swap_f32(self, value: &mut f32) { + let value = unsafe { &mut *(value as *mut f32 as *mut u32) }; - self.swap_u32( value ); + self.swap_u32(value); } #[inline] - pub fn swap_f64( self, value: &mut f64 ) { - let value = unsafe { - &mut *(value as *mut f64 as *mut u64) - }; + pub fn swap_f64(self, value: &mut f64) { + let value = unsafe { &mut *(value as *mut f64 as *mut u64) }; - self.swap_u64( value ); + self.swap_u64(value); } #[inline] - pub fn swap_slice_f32( self, slice: &mut [f32] ) { - let slice = unsafe { - core::slice::from_raw_parts_mut( slice.as_mut_ptr() as *mut u32, slice.len() ) - }; + pub fn swap_slice_f32(self, slice: &mut [f32]) { + let slice = + unsafe { core::slice::from_raw_parts_mut(slice.as_mut_ptr() as *mut u32, slice.len()) }; - self.swap_slice_u32( slice ); + self.swap_slice_u32(slice); } #[inline] - pub fn swap_slice_f64( self, slice: &mut [f64] ) { - let slice = unsafe { - core::slice::from_raw_parts_mut( slice.as_mut_ptr() as *mut u64, slice.len() ) - }; + pub fn swap_slice_f64(self, slice: &mut [f64]) { + let slice = + unsafe { core::slice::from_raw_parts_mut(slice.as_mut_ptr() as *mut u64, slice.len()) }; - self.swap_slice_u64( slice ); + self.swap_slice_u64(slice); } } diff --git a/src/error.rs b/src/error.rs index 3f5a0d4..124e741 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,13 +1,8 @@ -use { - std::{ - fmt, - io - } -}; +use std::{fmt, io}; #[derive(Debug)] pub struct Error { - kind: ErrorKind + kind: ErrorKind, } #[derive(Debug)] @@ -23,50 +18,50 @@ pub enum ErrorKind { UnexpectedEndOfOutputBuffer, InputBufferIsTooSmall { actual_size: usize, - expected_size: usize + expected_size: usize, }, OutputBufferIsTooSmall { actual_size: usize, - expected_size: usize + expected_size: usize, }, LengthIsNotTheSameAsLengthAttribute { - field_name: &'static str + field_name: &'static str, }, ExpectedConstant { - constant: &'static [u8] + constant: &'static [u8], }, Unsized, EndiannessMismatch, - IoError( io::Error ) + IoError(io::Error), } impl Error { #[inline] - fn new( kind: ErrorKind ) -> Self { + fn new(kind: ErrorKind) -> Self { Error { kind } } - pub fn custom( message: impl fmt::Display ) -> Self { + pub fn custom(message: impl fmt::Display) -> Self { // The LLVM optimizer doesn't like us adding a new variant, // so instead we reuse the `IoError` one. Error { - kind: ErrorKind::IoError( io::Error::new( io::ErrorKind::Other, message.to_string() ) ) + kind: ErrorKind::IoError(io::Error::new(io::ErrorKind::Other, message.to_string())), } } #[inline] - pub(crate) fn from_io_error( error: io::Error ) -> Self { + pub(crate) fn from_io_error(error: io::Error) -> Self { Error { - kind: ErrorKind::IoError( error ) + kind: ErrorKind::IoError(error), } } } -impl From< Error > for io::Error { - fn from( error: Error ) -> Self { - if let ErrorKind::IoError( error ) = error.kind { +impl From for io::Error { + fn from(error: Error) -> Self { + if let ErrorKind::IoError(error) = error.kind { return error; } @@ -77,17 +72,17 @@ impl From< Error > for io::Error { io::ErrorKind::InvalidData }; - io::Error::new( kind, format!( "{}", error ) ) + io::Error::new(kind, format!("{}", error)) } } #[inline] -pub fn get_error_kind( error: &Error ) -> &ErrorKind { +pub fn get_error_kind(error: &Error) -> &ErrorKind { &error.kind } impl fmt::Display for Error { - fn fmt( &self, fmt: &mut fmt::Formatter<'_> ) -> fmt::Result { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { ErrorKind::InvalidChar => write!( fmt, "out of range char" ), ErrorKind::InvalidEnumVariant => write!( fmt, "invalid enum variant" ), @@ -110,105 +105,160 @@ impl fmt::Display for Error { } impl std::error::Error for Error { - fn source( &self ) -> Option< &(dyn std::error::Error + 'static) > { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self.kind { - ErrorKind::IoError( ref error ) => Some( error ), - _ => None + ErrorKind::IoError(ref error) => Some(error), + _ => None, } } } pub trait IsEof { - fn is_eof( &self ) -> bool; + fn is_eof(&self) -> bool; } impl IsEof for Error { - fn is_eof( &self ) -> bool { + fn is_eof(&self) -> bool { match self.kind { - ErrorKind::UnexpectedEndOfInput | - ErrorKind::UnexpectedEndOfOutputBuffer => true, - ErrorKind::IoError( ref error ) => error.kind() == std::io::ErrorKind::UnexpectedEof, - _ => false + ErrorKind::UnexpectedEndOfInput | ErrorKind::UnexpectedEndOfOutputBuffer => true, + ErrorKind::IoError(ref error) => error.kind() == std::io::ErrorKind::UnexpectedEof, + _ => false, } } } #[cold] -pub fn error_invalid_string_utf8< T >( _: std::string::FromUtf8Error ) -> T where T: From< Error > { - T::from( Error::new( ErrorKind::InvalidUtf8 ) ) +pub fn error_invalid_string_utf8(_: std::string::FromUtf8Error) -> T +where + T: From, +{ + T::from(Error::new(ErrorKind::InvalidUtf8)) } #[cold] -pub fn error_invalid_str_utf8< T >( _: std::str::Utf8Error ) -> T where T: From< Error > { - T::from( Error::new( ErrorKind::InvalidUtf8 ) ) +pub fn error_invalid_str_utf8(_: std::str::Utf8Error) -> T +where + T: From, +{ + T::from(Error::new(ErrorKind::InvalidUtf8)) } #[cold] -pub fn error_length_is_not_the_same_as_length_attribute< T >( field_name: &'static str ) -> T where T: From< Error > { - T::from( Error::new( ErrorKind::LengthIsNotTheSameAsLengthAttribute { field_name } ) ) +pub fn error_length_is_not_the_same_as_length_attribute(field_name: &'static str) -> T +where + T: From, +{ + T::from(Error::new(ErrorKind::LengthIsNotTheSameAsLengthAttribute { + field_name, + })) } #[cold] -pub fn error_out_of_range_length< T >() -> T where T: From< Error > { - T::from( Error::new( ErrorKind::OutOfRangeLength ) ) +pub fn error_out_of_range_length() -> T +where + T: From, +{ + T::from(Error::new(ErrorKind::OutOfRangeLength)) } #[cold] -pub fn error_invalid_enum_variant< T >() -> T where T: From< Error > { - T::from( Error::new( ErrorKind::InvalidEnumVariant ) ) +pub fn error_invalid_enum_variant() -> T +where + T: From, +{ + T::from(Error::new(ErrorKind::InvalidEnumVariant)) } #[cold] -pub fn error_out_of_range_char< T >() -> T where T: From< Error > { - T::from( Error::new( ErrorKind::InvalidChar ) ) +pub fn error_out_of_range_char() -> T +where + T: From, +{ + T::from(Error::new(ErrorKind::InvalidChar)) } #[cold] -pub fn error_too_big_usize_for_this_architecture< T >() -> T where T: From< Error > { - T::from( Error::new( ErrorKind::OutOfRangeUsize ) ) +pub fn error_too_big_usize_for_this_architecture() -> T +where + T: From, +{ + T::from(Error::new(ErrorKind::OutOfRangeUsize)) } #[cold] -pub fn error_end_of_input< T >() -> T where T: From< Error > { - T::from( Error::new( ErrorKind::UnexpectedEndOfInput ) ) +pub fn error_end_of_input() -> T +where + T: From, +{ + T::from(Error::new(ErrorKind::UnexpectedEndOfInput)) } #[cold] -pub fn error_end_of_output_buffer< T >() -> T where T: From< Error > { - T::from( Error::new( ErrorKind::UnexpectedEndOfOutputBuffer ) ) +pub fn error_end_of_output_buffer() -> T +where + T: From, +{ + T::from(Error::new(ErrorKind::UnexpectedEndOfOutputBuffer)) } #[cold] -pub fn error_input_buffer_is_too_small< T >( actual_size: usize, expected_size: usize ) -> T where T: From< Error > { - T::from( Error::new( ErrorKind::InputBufferIsTooSmall { actual_size, expected_size } ) ) +pub fn error_input_buffer_is_too_small(actual_size: usize, expected_size: usize) -> T +where + T: From, +{ + T::from(Error::new(ErrorKind::InputBufferIsTooSmall { + actual_size, + expected_size, + })) } #[cold] -pub fn error_output_buffer_is_too_small< T >( actual_size: usize, expected_size: usize ) -> T where T: From< Error > { - T::from( Error::new( ErrorKind::OutputBufferIsTooSmall { actual_size, expected_size } ) ) +pub fn error_output_buffer_is_too_small(actual_size: usize, expected_size: usize) -> T +where + T: From, +{ + T::from(Error::new(ErrorKind::OutputBufferIsTooSmall { + actual_size, + expected_size, + })) } #[cold] -pub fn error_zero_non_zero< T >() -> T where T: From< Error > { - T::from( Error::new( ErrorKind::ZeroNonZero ) ) +pub fn error_zero_non_zero() -> T +where + T: From, +{ + T::from(Error::new(ErrorKind::ZeroNonZero)) } #[cold] -pub fn error_invalid_system_time< T >() -> T where T: From< Error > { - T::from( Error::new( ErrorKind::InvalidSystemTime ) ) +pub fn error_invalid_system_time() -> T +where + T: From, +{ + T::from(Error::new(ErrorKind::InvalidSystemTime)) } #[cold] -pub fn error_expected_constant< T >( constant: &'static [u8] ) -> T where T: From< Error > { - T::from( Error::new( ErrorKind::ExpectedConstant { constant } ) ) +pub fn error_expected_constant(constant: &'static [u8]) -> T +where + T: From, +{ + T::from(Error::new(ErrorKind::ExpectedConstant { constant })) } #[cold] -pub fn error_unsized< T >() -> T where T: From< Error > { - T::from( Error::new( ErrorKind::Unsized ) ) +pub fn error_unsized() -> T +where + T: From, +{ + T::from(Error::new(ErrorKind::Unsized)) } #[cold] -pub fn error_endianness_mismatch< T >() -> T where T: From< Error > { - T::from( Error::new( ErrorKind::EndiannessMismatch ) ) +pub fn error_endianness_mismatch() -> T +where + T: From, +{ + T::from(Error::new(ErrorKind::EndiannessMismatch)) } diff --git a/src/ext_chrono.rs b/src/ext_chrono.rs index 5397a71..90b9eb7 100644 --- a/src/ext_chrono.rs +++ b/src/ext_chrono.rs @@ -1,26 +1,17 @@ use { - chrono::{ - DateTime, - TimeZone, - Utc - }, - crate::{ - Context, - Readable, - Reader, - Writable, - Writer - } + crate::{Context, Readable, Reader, Writable, Writer}, + chrono::{DateTime, TimeZone, Utc}, }; -impl< 'a, C > Readable< 'a, C > for DateTime< Utc > - where C: Context +impl<'a, C> Readable<'a, C> for DateTime +where + C: Context, { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { + fn read_from>(reader: &mut R) -> Result { let seconds = reader.read_i64()?; let subsec_nanos = reader.read_u32()?; - Ok( Utc.timestamp( seconds, subsec_nanos ) ) + Ok(Utc.timestamp(seconds, subsec_nanos)) } #[inline] @@ -29,18 +20,18 @@ impl< 'a, C > Readable< 'a, C > for DateTime< Utc > } } - -impl< C > Writable< C > for DateTime< Utc > - where C: Context +impl Writable for DateTime +where + C: Context, { #[inline] - fn write_to< T: ?Sized + Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error > { - writer.write_i64( self.timestamp() )?; - writer.write_u32( self.timestamp_subsec_nanos() ) + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error> { + writer.write_i64(self.timestamp())?; + writer.write_u32(self.timestamp_subsec_nanos()) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Ok( 12 ) + fn bytes_needed(&self) -> Result { + Ok(12) } } diff --git a/src/ext_indexmap.rs b/src/ext_indexmap.rs index 81767ea..866c90f 100644 --- a/src/ext_indexmap.rs +++ b/src/ext_indexmap.rs @@ -1,36 +1,20 @@ use { - crate::{ - Context, - Readable, - Reader, - Writable, - Writer, - private::{ - write_length - } - }, - indexmap::{ - IndexMap, - IndexSet - }, - std::{ - hash::{ - BuildHasher, - Hash - } - } + crate::{private::write_length, Context, Readable, Reader, Writable, Writer}, + indexmap::{IndexMap, IndexSet}, + std::hash::{BuildHasher, Hash}, }; -impl< 'a, C, K, V, S > Readable< 'a, C > for IndexMap< K, V, S > - where C: Context, - K: Readable< 'a, C > + Eq + Hash, - V: Readable< 'a, C >, - S: BuildHasher + Default +impl<'a, C, K, V, S> Readable<'a, C> for IndexMap +where + C: Context, + K: Readable<'a, C> + Eq + Hash, + V: Readable<'a, C>, + S: BuildHasher + Default, { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - let length = crate::private::read_length( reader )?; - reader.read_collection( length ) + fn read_from>(reader: &mut R) -> Result { + let length = crate::private::read_length(reader)?; + reader.read_collection(length) } #[inline] @@ -39,15 +23,16 @@ impl< 'a, C, K, V, S > Readable< 'a, C > for IndexMap< K, V, S > } } -impl< 'a, C, T, S > Readable< 'a, C > for IndexSet< T, S > - where C: Context, - T: Readable< 'a, C > + Eq + Hash, - S: BuildHasher + Default +impl<'a, C, T, S> Readable<'a, C> for IndexSet +where + C: Context, + T: Readable<'a, C> + Eq + Hash, + S: BuildHasher + Default, { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - let length = crate::private::read_length( reader )?; - reader.read_collection( length ) + fn read_from>(reader: &mut R) -> Result { + let length = crate::private::read_length(reader)?; + reader.read_collection(length) } #[inline] @@ -56,49 +41,51 @@ impl< 'a, C, T, S > Readable< 'a, C > for IndexSet< T, S > } } -impl< C, K, V, S > Writable< C > for IndexMap< K, V, S > - where C: Context, - K: Writable< C >, - V: Writable< C > +impl Writable for IndexMap +where + C: Context, + K: Writable, + V: Writable, { #[inline] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - write_length( self.len(), writer )?; - writer.write_collection( self.iter() ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + write_length(self.len(), writer)?; + writer.write_collection(self.iter()) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - unsafe_is_length!( self.len() ); + fn bytes_needed(&self) -> Result { + unsafe_is_length!(self.len()); - let mut count = std::mem::size_of::< u32 >(); + let mut count = std::mem::size_of::(); for (key, value) in self { count += key.bytes_needed()? + value.bytes_needed()?; } - Ok( count ) + Ok(count) } } -impl< C, T, S > Writable< C > for IndexSet< T, S > - where C: Context, - T: Writable< C > +impl Writable for IndexSet +where + C: Context, + T: Writable, { #[inline] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - write_length( self.len(), writer )?; - writer.write_collection( self.iter() ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + write_length(self.len(), writer)?; + writer.write_collection(self.iter()) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - unsafe_is_length!( self.len() ); + fn bytes_needed(&self) -> Result { + unsafe_is_length!(self.len()); - let mut count = std::mem::size_of::< u32 >(); + let mut count = std::mem::size_of::(); for value in self { count += value.bytes_needed()?; } - Ok( count ) + Ok(count) } } diff --git a/src/ext_regex.rs b/src/ext_regex.rs index 5a01c6c..233baa6 100644 --- a/src/ext_regex.rs +++ b/src/ext_regex.rs @@ -1,25 +1,17 @@ use { - regex::{ - Regex - }, - crate::{ - Context, - Readable, - Reader, - Writable, - Writer - } + crate::{Context, Readable, Reader, Writable, Writer}, + regex::Regex, }; - -impl< 'a, C > Readable< 'a, C > for Regex - where C: Context +impl<'a, C> Readable<'a, C> for Regex +where + C: Context, { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - let regex: std::borrow::Cow< str > = reader.read_value()?; - Regex::new( ®ex ).map_err( |error| { - crate::error::Error::custom( format!( "failed to read a regex: {}", error ) ).into() + fn read_from>(reader: &mut R) -> Result { + let regex: std::borrow::Cow = reader.read_value()?; + Regex::new(®ex).map_err(|error| { + crate::error::Error::custom(format!("failed to read a regex: {}", error)).into() }) } @@ -29,17 +21,17 @@ impl< 'a, C > Readable< 'a, C > for Regex } } - -impl< C > Writable< C > for Regex - where C: Context +impl Writable for Regex +where + C: Context, { #[inline] - fn write_to< T: ?Sized + Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error > { - self.as_str().write_to( writer ) + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error> { + self.as_str().write_to(writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Writable::< C >::bytes_needed( self.as_str() ) + fn bytes_needed(&self) -> Result { + Writable::::bytes_needed(self.as_str()) } } diff --git a/src/ext_smallvec.rs b/src/ext_smallvec.rs index d86708a..dae726b 100644 --- a/src/ext_smallvec.rs +++ b/src/ext_smallvec.rs @@ -1,28 +1,20 @@ use { - crate::{ - Context, - Readable, - Reader, - Writable, - Writer - }, - smallvec::{ - Array, - SmallVec - } + crate::{Context, Readable, Reader, Writable, Writer}, + smallvec::{Array, SmallVec}, }; -impl< 'a, C, A > Readable< 'a, C > for SmallVec< A > - where C: Context, - A: Array, - ::Item: Readable< 'a, C > +impl<'a, C, A> Readable<'a, C> for SmallVec +where + C: Context, + A: Array, + ::Item: Readable<'a, C>, { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - let length = crate::private::read_length( reader )?; + fn read_from>(reader: &mut R) -> Result { + let length = crate::private::read_length(reader)?; // TODO: This can be more efficient if we directly read into the `SmallVec`. - let value = reader.read_vec( length )?; - Ok( value.into() ) + let value = reader.read_vec(length)?; + Ok(value.into()) } #[inline] @@ -31,19 +23,19 @@ impl< 'a, C, A > Readable< 'a, C > for SmallVec< A > } } - -impl< C, A > Writable< C > for SmallVec< A > - where C: Context, - A: Array, - ::Item: Writable< C > +impl Writable for SmallVec +where + C: Context, + A: Array, + ::Item: Writable, { #[inline] - fn write_to< T: ?Sized + Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error > { - self.as_slice().write_to( writer ) + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error> { + self.as_slice().write_to(writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Writable::< C >::bytes_needed( self.as_slice() ) + fn bytes_needed(&self) -> Result { + Writable::::bytes_needed(self.as_slice()) } } diff --git a/src/ext_uuid.rs b/src/ext_uuid.rs index c6cbdeb..5716f90 100644 --- a/src/ext_uuid.rs +++ b/src/ext_uuid.rs @@ -1,22 +1,16 @@ use { - crate::{ - Context, - Readable, - Reader, - Writable, - Writer - }, - uuid::Uuid + crate::{Context, Readable, Reader, Writable, Writer}, + uuid::Uuid, }; - const UUID_SIZE: usize = 16; -impl< 'a, C > Readable< 'a, C > for Uuid - where C: Context +impl<'a, C> Readable<'a, C> for Uuid +where + C: Context, { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { + fn read_from>(reader: &mut R) -> Result { let mut buffer = [0; UUID_SIZE]; reader.read_bytes(&mut buffer)?; Ok(Uuid::from_bytes(buffer)) @@ -28,17 +22,17 @@ impl< 'a, C > Readable< 'a, C > for Uuid } } - -impl< C > Writable< C > for Uuid - where C: Context +impl Writable for Uuid +where + C: Context, { #[inline] - fn write_to< T: ?Sized + Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error > { + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error> { writer.write_bytes(self.as_bytes()) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { + fn bytes_needed(&self) -> Result { Ok(UUID_SIZE) } } diff --git a/src/lib.rs b/src/lib.rs index 26ba12a..d024579 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,17 +3,17 @@ mod error; #[macro_use] mod utils; +mod circular_buffer; +mod context; +mod endianness; mod readable; mod readable_impl; mod readable_unsized_impl; mod reader; +mod varint; mod writable; mod writable_impl; mod writer; -mod context; -mod endianness; -mod varint; -mod circular_buffer; #[cfg(feature = "chrono")] mod ext_chrono; @@ -45,213 +45,221 @@ pub use crate::reader::Reader; pub use crate::writable::Writable; pub use crate::writer::Writer; -pub use crate::endianness::Endianness; pub use crate::context::{BigEndian, Context, LittleEndian}; +pub use crate::endianness::Endianness; pub use crate::error::{Error, IsEof}; #[cfg(test)] mod tests { - use std::io; use std::borrow::Cow; + use std::io; - use super::{ - Reader, - Readable, - Writer, - Writable, - Context, - Endianness - }; + use super::{Context, Endianness, Readable, Reader, Writable, Writer}; #[derive(PartialEq, Debug)] struct SimpleStruct { a: u8, b: u8, - c: u8 + c: u8, } - impl< C: Context > Writable< C > for SimpleStruct { - fn write_to< T: ?Sized + Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error > { - writer.write_value( &self.a )?; - writer.write_value( &self.b )?; - writer.write_value( &self.c )?; + impl Writable for SimpleStruct { + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error> { + writer.write_value(&self.a)?; + writer.write_value(&self.b)?; + writer.write_value(&self.c)?; Ok(()) } } - impl< 'a, C: Context > Readable< 'a, C > for SimpleStruct { - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { + impl<'a, C: Context> Readable<'a, C> for SimpleStruct { + fn read_from>(reader: &mut R) -> Result { let a = reader.read_u8()?; let b = reader.read_u8()?; let c = reader.read_u8()?; - Ok( SimpleStruct { a, b, c } ) + Ok(SimpleStruct { a, b, c }) } } #[test] fn simple_write_to_vec() { let value = SimpleStruct { a: 1, b: 2, c: 3 }; - let data = value.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap(); - assert_eq!( data, vec![ 1, 2, 3 ] ); + let data = value.write_to_vec_with_ctx(Endianness::NATIVE).unwrap(); + assert_eq!(data, vec![1, 2, 3]); } #[test] fn simple_read_from_stream_unbuffered() { - let data = vec![ 1, 2, 3 ]; - let cursor = io::Cursor::new( data ); - let value = SimpleStruct::read_from_stream_unbuffered_with_ctx( Endianness::NATIVE, cursor ).unwrap(); - assert_eq!( value, SimpleStruct { a: 1, b: 2, c: 3 } ); + let data = vec![1, 2, 3]; + let cursor = io::Cursor::new(data); + let value = + SimpleStruct::read_from_stream_unbuffered_with_ctx(Endianness::NATIVE, cursor).unwrap(); + assert_eq!(value, SimpleStruct { a: 1, b: 2, c: 3 }); } #[test] fn simple_read_from_stream_buffered() { - let data = vec![ 1, 2, 3 ]; - let cursor = io::Cursor::new( data ); - let value = SimpleStruct::read_from_stream_buffered_with_ctx( Endianness::NATIVE, cursor ).unwrap(); - assert_eq!( value, SimpleStruct { a: 1, b: 2, c: 3 } ); + let data = vec![1, 2, 3]; + let cursor = io::Cursor::new(data); + let value = + SimpleStruct::read_from_stream_buffered_with_ctx(Endianness::NATIVE, cursor).unwrap(); + assert_eq!(value, SimpleStruct { a: 1, b: 2, c: 3 }); } #[test] fn simple_read_from_buffer() { - let data = vec![ 1, 2, 3 ]; - let value = SimpleStruct::read_from_buffer_with_ctx( Endianness::NATIVE, &data ).unwrap(); - assert_eq!( value, SimpleStruct { a: 1, b: 2, c: 3 } ); + let data = vec![1, 2, 3]; + let value = SimpleStruct::read_from_buffer_with_ctx(Endianness::NATIVE, &data).unwrap(); + assert_eq!(value, SimpleStruct { a: 1, b: 2, c: 3 }); } #[test] fn simple_read_bytes_from_buffer_owned() { - let data = vec![ 2, 0, 0, 0, 12, 34 ]; - let value: Cow< [u8] > = Readable::read_from_buffer_copying_data_with_ctx( Endianness::LittleEndian, &data ).unwrap(); - assert_eq!( &*value, &[12, 34] ); - assert_ne!( value.as_ptr(), data[ 4.. ].as_ptr() ); + let data = vec![2, 0, 0, 0, 12, 34]; + let value: Cow<[u8]> = + Readable::read_from_buffer_copying_data_with_ctx(Endianness::LittleEndian, &data) + .unwrap(); + assert_eq!(&*value, &[12, 34]); + assert_ne!(value.as_ptr(), data[4..].as_ptr()); } #[test] fn simple_read_bytes_from_buffer_borrowed() { - let data = vec![ 2, 0, 0, 0, 12, 34 ]; - let value: Cow< [u8] > = Readable::read_from_buffer_with_ctx( Endianness::LittleEndian, &data ).unwrap(); - assert_eq!( &*value, &[12, 34] ); - assert_eq!( value.as_ptr(), data[ 4.. ].as_ptr() ); + let data = vec![2, 0, 0, 0, 12, 34]; + let value: Cow<[u8]> = + Readable::read_from_buffer_with_ctx(Endianness::LittleEndian, &data).unwrap(); + assert_eq!(&*value, &[12, 34]); + assert_eq!(value.as_ptr(), data[4..].as_ptr()); } #[test] fn read_from_buffer_copying_data_with_default_ctx() { - let data = vec![ 2, 0 ]; - let value = u16::read_from_buffer_copying_data( &data ).unwrap(); - assert_eq!( value, 2 ); + let data = vec![2, 0]; + let value = u16::read_from_buffer_copying_data(&data).unwrap(); + assert_eq!(value, 2); } #[test] fn read_from_buffer_borrowed_with_default_ctx() { - let data = vec![ 2, 0 ]; - let value = u16::read_from_buffer( &data ).unwrap(); - assert_eq!( value, 2 ); + let data = vec![2, 0]; + let value = u16::read_from_buffer(&data).unwrap(); + assert_eq!(value, 2); } #[test] fn read_from_stream_unbuffered_with_default_ctx() { - let data = vec![ 2, 0 ]; - let value = u16::read_from_stream_unbuffered( io::Cursor::new( data ) ).unwrap(); - assert_eq!( value, 2 ); + let data = vec![2, 0]; + let value = u16::read_from_stream_unbuffered(io::Cursor::new(data)).unwrap(); + assert_eq!(value, 2); } #[test] fn read_from_stream_buffered_with_default_ctx() { - let data = vec![ 2, 0 ]; - let value = u16::read_from_stream_buffered( io::Cursor::new( data ) ).unwrap(); - assert_eq!( value, 2 ); + let data = vec![2, 0]; + let value = u16::read_from_stream_buffered(io::Cursor::new(data)).unwrap(); + assert_eq!(value, 2); } #[test] fn write_to_buffer_with_default_ctx() { let mut buffer = [0, 0]; - 2_u16.write_to_buffer( &mut buffer ).unwrap(); - assert_eq!( buffer, [2, 0] ); + 2_u16.write_to_buffer(&mut buffer).unwrap(); + assert_eq!(buffer, [2, 0]); } #[test] fn write_to_vec_with_default_ctx() { let buffer = 2_u16.write_to_vec().unwrap(); - assert_eq!( buffer, [2, 0] ); + assert_eq!(buffer, [2, 0]); } #[test] fn write_to_stream_with_default_ctx() { let mut buffer = [0, 0]; - 2_u16.write_to_stream( io::Cursor::new( &mut buffer[..] ) ).unwrap(); - assert_eq!( buffer, [2, 0] ); + 2_u16 + .write_to_stream(io::Cursor::new(&mut buffer[..])) + .unwrap(); + assert_eq!(buffer, [2, 0]); } #[test] fn read_write_u8_vec() { - let original: Vec< u8 > = vec![ 1, 2, 3 ]; - let serialized = original.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap(); - let deserialized: Vec< u8 > = Vec::< u8 >::read_from_buffer_with_ctx( Endianness::NATIVE, &serialized ).unwrap(); - assert_eq!( original, deserialized ); + let original: Vec = vec![1, 2, 3]; + let serialized = original.write_to_vec_with_ctx(Endianness::NATIVE).unwrap(); + let deserialized: Vec = + Vec::::read_from_buffer_with_ctx(Endianness::NATIVE, &serialized).unwrap(); + assert_eq!(original, deserialized); } #[test] fn read_write_u64_vec() { - let original: Vec< u64 > = vec![ 1, 2, 3 ]; - let serialized = original.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap(); - let deserialized: Vec< u64 > = Vec::< u64 >::read_from_buffer_with_ctx( Endianness::NATIVE, &serialized ).unwrap(); - assert_eq!( original, deserialized ); + let original: Vec = vec![1, 2, 3]; + let serialized = original.write_to_vec_with_ctx(Endianness::NATIVE).unwrap(); + let deserialized: Vec = + Vec::::read_from_buffer_with_ctx(Endianness::NATIVE, &serialized).unwrap(); + assert_eq!(original, deserialized); } #[test] fn read_write_string() { let original: String = "Hello world!".to_owned(); - let serialized = original.write_to_vec_with_ctx( Endianness::NATIVE ).unwrap(); - let deserialized: String = String::read_from_buffer_with_ctx( Endianness::NATIVE, &serialized ).unwrap(); - assert_eq!( original, deserialized ); + let serialized = original.write_to_vec_with_ctx(Endianness::NATIVE).unwrap(); + let deserialized: String = + String::read_from_buffer_with_ctx(Endianness::NATIVE, &serialized).unwrap(); + assert_eq!(original, deserialized); } #[cfg(not(miri))] #[test] fn read_big_vector_of_vectors_from_stream_buffered() { - const fn hash32( x: u32 ) -> u32 { - let mut x = x.wrapping_mul( 0xa4d94a4f ); + const fn hash32(x: u32) -> u32 { + let mut x = x.wrapping_mul(0xa4d94a4f); let a = x >> 16; let b = x >> 30; x ^= a >> b; - x.wrapping_mul( 0xa4d94a4f ) + x.wrapping_mul(0xa4d94a4f) } struct TestStream { - buffer: Vec< u8 >, - position: usize + buffer: Vec, + position: usize, } impl io::Read for TestStream { - fn read( &mut self, output: &mut [u8] ) -> Result< usize, io::Error > { + fn read(&mut self, output: &mut [u8]) -> Result { if self.position >= self.buffer.len() || output.len() == 0 { return Ok(0); } - let random = hash32( self.position as u32 + output.len() as u32 ) as usize; - let length = std::cmp::min( random % output.len() + 1, self.buffer.len() - self.position ); - output[ ..length ].copy_from_slice( &self.buffer[ self.position..self.position + length ] ); + let random = hash32(self.position as u32 + output.len() as u32) as usize; + let length = + std::cmp::min(random % output.len() + 1, self.buffer.len() - self.position); + output[..length] + .copy_from_slice(&self.buffer[self.position..self.position + length]); self.position += length; - Ok( length ) + Ok(length) } } - let mut original: Vec< Vec< u8 > > = Vec::new(); + let mut original: Vec> = Vec::new(); for nth in 0..10000 { let mut buffer = Vec::new(); - let random = hash32( nth as u32 ); + let random = hash32(nth as u32); for byte in 0..(random % 128) as u8 { - buffer.push( byte ); + buffer.push(byte); } - original.push( buffer ); + original.push(buffer); } let serialized = original.write_to_vec().unwrap(); - let stream = TestStream { buffer: serialized, position: 0 }; - let deserialized: Vec< Vec< u8 > > = Readable::read_from_stream_buffered( stream ).unwrap(); - assert_eq!( original, deserialized ); + let stream = TestStream { + buffer: serialized, + position: 0, + }; + let deserialized: Vec> = Readable::read_from_stream_buffered(stream).unwrap(); + assert_eq!(original, deserialized); } } diff --git a/src/private.rs b/src/private.rs index 6468650..72b12ff 100644 --- a/src/private.rs +++ b/src/private.rs @@ -1,253 +1,268 @@ use { crate::{ - Context, - Error, - Readable, - Reader, - Writable, - Writer, - error::{ - error_expected_constant, - error_invalid_string_utf8 - } + error::{error_expected_constant, error_invalid_string_utf8}, + Context, Error, Readable, Reader, Writable, Writer, }, - std::{ - borrow::{ - Cow - } - } + std::borrow::Cow, }; -pub use crate::varint::VarInt64; pub use crate::error::{ - ErrorKind, - - error_length_is_not_the_same_as_length_attribute, - error_out_of_range_length, - error_invalid_enum_variant, - error_invalid_str_utf8, - error_unsized, - error_endianness_mismatch, - - get_error_kind, + error_endianness_mismatch, error_invalid_enum_variant, error_invalid_str_utf8, + error_length_is_not_the_same_as_length_attribute, error_out_of_range_length, error_unsized, + get_error_kind, ErrorKind, }; pub use crate::utils::ZeroCopyable; +pub use crate::varint::VarInt64; pub use memoffset::offset_of; #[inline] -pub fn vec_to_string< E >( bytes: Vec< u8 > ) -> Result< String, E > where E: From< Error > { - String::from_utf8( bytes ).map_err( error_invalid_string_utf8 ) +pub fn vec_to_string(bytes: Vec) -> Result +where + E: From, +{ + String::from_utf8(bytes).map_err(error_invalid_string_utf8) } #[inline] -pub fn cow_bytes_to_cow_str< E >( bytes: Cow<'_, [u8] > ) -> Result< Cow<'_, str >, E > where E: From< Error > { +pub fn cow_bytes_to_cow_str(bytes: Cow<'_, [u8]>) -> Result, E> +where + E: From, +{ match bytes { - Cow::Borrowed( bytes ) => { - std::str::from_utf8( bytes ) - .map( Cow::Borrowed ) - .map_err( error_invalid_str_utf8 ) - }, - Cow::Owned( bytes ) => { - String::from_utf8( bytes ) - .map( Cow::Owned ) - .map_err( error_invalid_string_utf8 ) - } + Cow::Borrowed(bytes) => std::str::from_utf8(bytes) + .map(Cow::Borrowed) + .map_err(error_invalid_str_utf8), + Cow::Owned(bytes) => String::from_utf8(bytes) + .map(Cow::Owned) + .map_err(error_invalid_string_utf8), } } #[inline] -pub fn write_length_u64_varint< C, W >( length: usize, writer: &mut W ) -> Result< (), C::Error > - where C: Context, - W: ?Sized + Writer< C > +pub fn write_length_u64_varint(length: usize, writer: &mut W) -> Result<(), C::Error> +where + C: Context, + W: ?Sized + Writer, { - let length = VarInt64::from( length as u64 ); - length.write_to( writer ) + let length = VarInt64::from(length as u64); + length.write_to(writer) } #[inline] -pub fn write_length_u64< C, W >( length: usize, writer: &mut W ) -> Result< (), C::Error > - where C: Context, - W: ?Sized + Writer< C > +pub fn write_length_u64(length: usize, writer: &mut W) -> Result<(), C::Error> +where + C: Context, + W: ?Sized + Writer, { - writer.write_u64( length as u64 ) + writer.write_u64(length as u64) } #[inline] -pub fn write_length_u32< C, W >( length: usize, writer: &mut W ) -> Result< (), C::Error > - where C: Context, - W: ?Sized + Writer< C > +pub fn write_length_u32(length: usize, writer: &mut W) -> Result<(), C::Error> +where + C: Context, + W: ?Sized + Writer, { if length as u64 > std::u32::MAX as u64 { - return Err( error_out_of_range_length() ); + return Err(error_out_of_range_length()); } - writer.write_u32( length as u32 ) + writer.write_u32(length as u32) } #[inline] -pub fn write_length_u16< C, W >( length: usize, writer: &mut W ) -> Result< (), C::Error > - where C: Context, - W: ?Sized + Writer< C > +pub fn write_length_u16(length: usize, writer: &mut W) -> Result<(), C::Error> +where + C: Context, + W: ?Sized + Writer, { if length as u64 > std::u16::MAX as u64 { - return Err( error_out_of_range_length() ); + return Err(error_out_of_range_length()); } - writer.write_u16( length as u16 ) + writer.write_u16(length as u16) } #[inline] -pub fn write_length_u8< C, W >( length: usize, writer: &mut W ) -> Result< (), C::Error > - where C: Context, - W: ?Sized + Writer< C > +pub fn write_length_u8(length: usize, writer: &mut W) -> Result<(), C::Error> +where + C: Context, + W: ?Sized + Writer, { if length as u64 > std::u8::MAX as u64 { - return Err( error_out_of_range_length() ); + return Err(error_out_of_range_length()); } - writer.write_u8( length as u8 ) + writer.write_u8(length as u8) } #[inline] -pub fn write_length_u7< C, W >( length: usize, writer: &mut W ) -> Result< (), C::Error > - where C: Context, - W: ?Sized + Writer< C > +pub fn write_length_u7(length: usize, writer: &mut W) -> Result<(), C::Error> +where + C: Context, + W: ?Sized + Writer, { if length > 0b01111111 { - return Err( error_out_of_range_length() ); + return Err(error_out_of_range_length()); } - writer.write_u8( length as u8 ) + writer.write_u8(length as u8) } #[inline] -pub fn write_length< C, W >( length: usize, writer: &mut W ) -> Result< (), C::Error > - where C: Context, - W: ?Sized + Writer< C > +pub fn write_length(length: usize, writer: &mut W) -> Result<(), C::Error> +where + C: Context, + W: ?Sized + Writer, { - write_length_u32( length, writer ) + write_length_u32(length, writer) } #[inline] -pub fn read_length_u64_varint< 'a, C, R >( reader: &mut R ) -> Result< usize, C::Error > - where C: Context, - R: Reader< 'a, C > +pub fn read_length_u64_varint<'a, C, R>(reader: &mut R) -> Result +where + C: Context, + R: Reader<'a, C>, { - let length: u64 = VarInt64::read_from( reader )?.into(); + let length: u64 = VarInt64::read_from(reader)?.into(); if length > std::usize::MAX as u64 { - return Err( error_out_of_range_length() ); + return Err(error_out_of_range_length()); } - Ok( length as usize ) + Ok(length as usize) } #[inline] -pub fn read_length_u64< 'a, C, R >( reader: &mut R ) -> Result< usize, C::Error > - where C: Context, - R: Reader< 'a, C > +pub fn read_length_u64<'a, C, R>(reader: &mut R) -> Result +where + C: Context, + R: Reader<'a, C>, { let length = reader.read_u64()?; if length > std::usize::MAX as u64 { - return Err( error_out_of_range_length() ); + return Err(error_out_of_range_length()); } - Ok( length as usize ) + Ok(length as usize) } #[inline] -pub fn read_length_u32< 'a, C, R >( reader: &mut R ) -> Result< usize, C::Error > - where C: Context, - R: Reader< 'a, C > +pub fn read_length_u32<'a, C, R>(reader: &mut R) -> Result +where + C: Context, + R: Reader<'a, C>, { - reader.read_u32().map( |value| value as usize ) + reader.read_u32().map(|value| value as usize) } #[inline] -pub fn read_length_u16< 'a, C, R >( reader: &mut R ) -> Result< usize, C::Error > - where C: Context, - R: Reader< 'a, C > +pub fn read_length_u16<'a, C, R>(reader: &mut R) -> Result +where + C: Context, + R: Reader<'a, C>, { - reader.read_u16().map( |value| value as usize ) + reader.read_u16().map(|value| value as usize) } #[inline] -pub fn read_length_u8< 'a, C, R >( reader: &mut R ) -> Result< usize, C::Error > - where C: Context, - R: Reader< 'a, C > +pub fn read_length_u8<'a, C, R>(reader: &mut R) -> Result +where + C: Context, + R: Reader<'a, C>, { - reader.read_u8().map( |value| value as usize ) + reader.read_u8().map(|value| value as usize) } #[inline] -pub fn read_length_u7< 'a, C, R >( reader: &mut R ) -> Result< usize, C::Error > - where C: Context, - R: Reader< 'a, C > +pub fn read_length_u7<'a, C, R>(reader: &mut R) -> Result +where + C: Context, + R: Reader<'a, C>, { let length = reader.read_u8()?; if length > 0b01111111 { - return Err( error_out_of_range_length() ); + return Err(error_out_of_range_length()); } - Ok( length as usize ) + Ok(length as usize) } #[inline] -pub fn read_length< 'a, C, R >( reader: &mut R ) -> Result< usize, C::Error > - where C: Context, - R: Reader< 'a, C > +pub fn read_length<'a, C, R>(reader: &mut R) -> Result +where + C: Context, + R: Reader<'a, C>, { - read_length_u32( reader ) + read_length_u32(reader) } pub trait IntoLength { - fn into_length( self ) -> usize; + fn into_length(self) -> usize; } impl IntoLength for usize { - fn into_length( self ) -> usize { self } + fn into_length(self) -> usize { + self + } } impl IntoLength for u32 { - fn into_length( self ) -> usize { self as usize } + fn into_length(self) -> usize { + self as usize + } } impl IntoLength for u16 { - fn into_length( self ) -> usize { self as usize } + fn into_length(self) -> usize { + self as usize + } } impl IntoLength for u8 { - fn into_length( self ) -> usize { self as usize } + fn into_length(self) -> usize { + self as usize + } } -impl< 'a, T > IntoLength for &'a T where T: IntoLength + Copy { - fn into_length( self ) -> usize { (*self).into_length() } +impl<'a, T> IntoLength for &'a T +where + T: IntoLength + Copy, +{ + fn into_length(self) -> usize { + (*self).into_length() + } } -impl< 'a, T > IntoLength for &'a mut T where T: IntoLength + Copy { - fn into_length( self ) -> usize { (*self).into_length() } +impl<'a, T> IntoLength for &'a mut T +where + T: IntoLength + Copy, +{ + fn into_length(self) -> usize { + (*self).into_length() + } } #[inline] -pub fn are_lengths_the_same( lhs: usize, rhs: impl IntoLength ) -> bool { +pub fn are_lengths_the_same(lhs: usize, rhs: impl IntoLength) -> bool { lhs == rhs.into_length() } -pub fn read_constant< 'a, C, R >( reader: &mut R, constant: &'static [u8] ) -> Result< (), C::Error > - where C: Context, - R: Reader< 'a, C > +pub fn read_constant<'a, C, R>(reader: &mut R, constant: &'static [u8]) -> Result<(), C::Error> +where + C: Context, + R: Reader<'a, C>, { - let is_ok = - if let Some( result ) = reader.read_bytes_borrowed( constant.len() ) { - result? == constant - } else { - // TODO: Do this more efficiently for sufficiently small constants. - let data: Vec< u8 > = reader.read_vec( constant.len() )?; - data == constant - }; + let is_ok = if let Some(result) = reader.read_bytes_borrowed(constant.len()) { + result? == constant + } else { + // TODO: Do this more efficiently for sufficiently small constants. + let data: Vec = reader.read_vec(constant.len())?; + data == constant + }; if !is_ok { - let error = error_expected_constant( constant ); - return Err( error ); + let error = error_expected_constant(constant); + return Err(error); } Ok(()) diff --git a/src/readable.rs b/src/readable.rs index 435b735..661d190 100644 --- a/src/readable.rs +++ b/src/readable.rs @@ -1,308 +1,344 @@ -use std::io::{ - Read -}; +use std::io::Read; use std::fs::File; -use std::path::Path; use std::marker::PhantomData; +use std::path::Path; -use crate::reader::Reader; +use crate::circular_buffer::CircularBuffer; use crate::context::{Context, DefaultContext}; use crate::endianness::Endianness; +use crate::reader::Reader; use crate::Error; -use crate::circular_buffer::CircularBuffer; -use crate::error::{ - error_end_of_input, - error_input_buffer_is_too_small -}; +use crate::error::{error_end_of_input, error_input_buffer_is_too_small}; -struct BufferReader< 'a, C > where C: Context { +struct BufferReader<'a, C> +where + C: Context, +{ context: C, ptr: *const u8, end: *const u8, - phantom: PhantomData< &'a [u8] > + phantom: PhantomData<&'a [u8]>, } -impl< 'a, C > BufferReader< 'a, C > where C: Context { +impl<'a, C> BufferReader<'a, C> +where + C: Context, +{ #[inline] - fn new( context: C, buffer: &'a [u8] ) -> Self { + fn new(context: C, buffer: &'a [u8]) -> Self { BufferReader { context, ptr: buffer.as_ptr(), - end: unsafe { buffer.as_ptr().add( buffer.len() ) }, - phantom: PhantomData + end: unsafe { buffer.as_ptr().add(buffer.len()) }, + phantom: PhantomData, } } } -impl< 'a, C: Context > Reader< 'a, C > for BufferReader< 'a, C > { +impl<'a, C: Context> Reader<'a, C> for BufferReader<'a, C> { #[inline(always)] - fn read_bytes( &mut self, output: &mut [u8] ) -> Result< (), C::Error > { + fn read_bytes(&mut self, output: &mut [u8]) -> Result<(), C::Error> { let length = output.len(); - if self.can_read_at_least( length ) == Some( false ) { - return Err( error_end_of_input() ); + if self.can_read_at_least(length) == Some(false) { + return Err(error_end_of_input()); } unsafe { - std::ptr::copy_nonoverlapping( self.ptr, output.as_mut_ptr(), length ); - self.ptr = self.ptr.add( length ); + std::ptr::copy_nonoverlapping(self.ptr, output.as_mut_ptr(), length); + self.ptr = self.ptr.add(length); } Ok(()) } #[inline(always)] - unsafe fn read_bytes_into_ptr( &mut self, output: *mut u8, length: usize ) -> Result< (), C::Error > { - if self.can_read_at_least( length ) == Some( false ) { - return Err( error_end_of_input() ); + unsafe fn read_bytes_into_ptr( + &mut self, + output: *mut u8, + length: usize, + ) -> Result<(), C::Error> { + if self.can_read_at_least(length) == Some(false) { + return Err(error_end_of_input()); } - unsafe { - std::ptr::copy_nonoverlapping( self.ptr, output, length ); - self.ptr = self.ptr.add( length ); + unsafe { + std::ptr::copy_nonoverlapping(self.ptr, output, length); + self.ptr = self.ptr.add(length); } Ok(()) } #[inline(always)] - fn peek_bytes( &mut self, output: &mut [u8] ) -> Result< (), C::Error > { + fn peek_bytes(&mut self, output: &mut [u8]) -> Result<(), C::Error> { let length = output.len(); - if self.can_read_at_least( length ) == Some( false ) { - return Err( error_end_of_input() ); + if self.can_read_at_least(length) == Some(false) { + return Err(error_end_of_input()); } unsafe { - std::ptr::copy_nonoverlapping( self.ptr, output.as_mut_ptr(), length ); + std::ptr::copy_nonoverlapping(self.ptr, output.as_mut_ptr(), length); } Ok(()) } #[inline(always)] - unsafe fn peek_bytes_into_ptr( &mut self, output: *mut u8, length: usize ) -> Result< (), C::Error > { - if self.can_read_at_least( length ) == Some( false ) { - return Err( error_end_of_input() ); + unsafe fn peek_bytes_into_ptr( + &mut self, + output: *mut u8, + length: usize, + ) -> Result<(), C::Error> { + if self.can_read_at_least(length) == Some(false) { + return Err(error_end_of_input()); } unsafe { - std::ptr::copy_nonoverlapping( self.ptr, output, length ); + std::ptr::copy_nonoverlapping(self.ptr, output, length); } Ok(()) } #[inline(always)] - fn skip_bytes( &mut self, length: usize ) -> Result< (), C::Error > { - if self.can_read_at_least( length ) == Some( false ) { - return Err( error_end_of_input() ); + fn skip_bytes(&mut self, length: usize) -> Result<(), C::Error> { + if self.can_read_at_least(length) == Some(false) { + return Err(error_end_of_input()); } unsafe { - self.ptr = self.ptr.add( length ); + self.ptr = self.ptr.add(length); } Ok(()) } #[inline(always)] - fn read_bytes_borrowed( &mut self, length: usize ) -> Option< Result< &'a [u8], C::Error > > { - if self.can_read_at_least( length ) == Some( false ) { - return Some( Err( error_end_of_input() ) ); + fn read_bytes_borrowed(&mut self, length: usize) -> Option> { + if self.can_read_at_least(length) == Some(false) { + return Some(Err(error_end_of_input())); } let slice; unsafe { - slice = std::slice::from_raw_parts( self.ptr, length ); - self.ptr = self.ptr.add( length ); + slice = std::slice::from_raw_parts(self.ptr, length); + self.ptr = self.ptr.add(length); } - Some( Ok( slice ) ) + Some(Ok(slice)) } #[inline(always)] - fn read_bytes_borrowed_from_reader< 'r >( &'r mut self, length: usize ) -> Option< Result< &'r [u8], C::Error > > { - if self.can_read_at_least( length ) == Some( false ) { - return Some( Err( error_end_of_input() ) ); + fn read_bytes_borrowed_from_reader<'r>( + &'r mut self, + length: usize, + ) -> Option> { + if self.can_read_at_least(length) == Some(false) { + return Some(Err(error_end_of_input())); } let slice; unsafe { - slice = std::slice::from_raw_parts( self.ptr, length ); - self.ptr = self.ptr.add( length ); + slice = std::slice::from_raw_parts(self.ptr, length); + self.ptr = self.ptr.add(length); } - Some( Ok( slice ) ) + Some(Ok(slice)) } #[inline(always)] - fn read_bytes_borrowed_until_eof( &mut self ) -> Option< &'a [u8] > { + fn read_bytes_borrowed_until_eof(&mut self) -> Option<&'a [u8]> { let length = self.end as usize - self.ptr as usize; let slice; unsafe { - slice = std::slice::from_raw_parts( self.ptr, length ); - self.ptr = self.ptr.add( length ); + slice = std::slice::from_raw_parts(self.ptr, length); + self.ptr = self.ptr.add(length); } - Some( slice ) + Some(slice) } #[inline(always)] - fn can_read_at_least( &self, size: usize ) -> Option< bool > { - Some( (self.end as usize - self.ptr as usize) >= size ) + fn can_read_at_least(&self, size: usize) -> Option { + Some((self.end as usize - self.ptr as usize) >= size) } #[inline(always)] - fn context( &self ) -> &C { + fn context(&self) -> &C { &self.context } #[inline(always)] - fn context_mut( &mut self ) -> &mut C { + fn context_mut(&mut self) -> &mut C { &mut self.context } } -struct CopyingBufferReader< 'ctx, 'a, C > where C: Context { +struct CopyingBufferReader<'ctx, 'a, C> +where + C: Context, +{ context: &'ctx mut C, ptr: *const u8, end: *const u8, - phantom: PhantomData< &'a [u8] > + phantom: PhantomData<&'a [u8]>, } -impl< 'ctx, 'a, C > CopyingBufferReader< 'ctx, 'a, C > where C: Context { +impl<'ctx, 'a, C> CopyingBufferReader<'ctx, 'a, C> +where + C: Context, +{ #[inline] - fn new( context: &'ctx mut C, buffer: &'a [u8] ) -> Self { + fn new(context: &'ctx mut C, buffer: &'a [u8]) -> Self { CopyingBufferReader { context, ptr: buffer.as_ptr(), - end: unsafe { buffer.as_ptr().add( buffer.len() ) }, - phantom: PhantomData + end: unsafe { buffer.as_ptr().add(buffer.len()) }, + phantom: PhantomData, } } } -impl< 'ctx, 'r, 'a, C: Context > Reader< 'r, C > for CopyingBufferReader< 'ctx, 'a, C > { +impl<'ctx, 'r, 'a, C: Context> Reader<'r, C> for CopyingBufferReader<'ctx, 'a, C> { #[inline(always)] - fn read_bytes( &mut self, output: &mut [u8] ) -> Result< (), C::Error > { + fn read_bytes(&mut self, output: &mut [u8]) -> Result<(), C::Error> { let length = output.len(); - if self.can_read_at_least( length ) == Some( false ) { - return Err( error_end_of_input() ); + if self.can_read_at_least(length) == Some(false) { + return Err(error_end_of_input()); } unsafe { - std::ptr::copy_nonoverlapping( self.ptr, output.as_mut_ptr(), length ); - self.ptr = self.ptr.add( length ); + std::ptr::copy_nonoverlapping(self.ptr, output.as_mut_ptr(), length); + self.ptr = self.ptr.add(length); } Ok(()) } #[inline(always)] - unsafe fn read_bytes_into_ptr( &mut self, output: *mut u8, length: usize ) -> Result< (), C::Error > { - if self.can_read_at_least( length ) == Some( false ) { - return Err( error_end_of_input() ); + unsafe fn read_bytes_into_ptr( + &mut self, + output: *mut u8, + length: usize, + ) -> Result<(), C::Error> { + if self.can_read_at_least(length) == Some(false) { + return Err(error_end_of_input()); } unsafe { - std::ptr::copy_nonoverlapping( self.ptr, output, length ); - self.ptr = self.ptr.add( length ); + std::ptr::copy_nonoverlapping(self.ptr, output, length); + self.ptr = self.ptr.add(length); } Ok(()) } #[inline(always)] - fn peek_bytes( &mut self, output: &mut [u8] ) -> Result< (), C::Error > { + fn peek_bytes(&mut self, output: &mut [u8]) -> Result<(), C::Error> { let length = output.len(); - if self.can_read_at_least( length ) == Some( false ) { - return Err( error_end_of_input() ); + if self.can_read_at_least(length) == Some(false) { + return Err(error_end_of_input()); } unsafe { - std::ptr::copy_nonoverlapping( self.ptr, output.as_mut_ptr(), length ); + std::ptr::copy_nonoverlapping(self.ptr, output.as_mut_ptr(), length); } Ok(()) } #[inline(always)] - unsafe fn peek_bytes_into_ptr( &mut self, output: *mut u8, length: usize ) -> Result< (), C::Error > { - if self.can_read_at_least( length ) == Some( false ) { - return Err( error_end_of_input() ); + unsafe fn peek_bytes_into_ptr( + &mut self, + output: *mut u8, + length: usize, + ) -> Result<(), C::Error> { + if self.can_read_at_least(length) == Some(false) { + return Err(error_end_of_input()); } unsafe { - std::ptr::copy_nonoverlapping( self.ptr, output, length ); + std::ptr::copy_nonoverlapping(self.ptr, output, length); } Ok(()) } #[inline(always)] - fn skip_bytes( &mut self, length: usize ) -> Result< (), C::Error > { - if self.can_read_at_least( length ) == Some( false ) { - return Err( error_end_of_input() ); + fn skip_bytes(&mut self, length: usize) -> Result<(), C::Error> { + if self.can_read_at_least(length) == Some(false) { + return Err(error_end_of_input()); } unsafe { - self.ptr = self.ptr.add( length ); + self.ptr = self.ptr.add(length); } Ok(()) } #[inline(always)] - fn read_bytes_borrowed_from_reader< 'reader >( &'reader mut self, length: usize ) -> Option< Result< &'reader [u8], C::Error > > { - if self.can_read_at_least( length ) == Some( false ) { - return Some( Err( error_end_of_input() ) ); + fn read_bytes_borrowed_from_reader<'reader>( + &'reader mut self, + length: usize, + ) -> Option> { + if self.can_read_at_least(length) == Some(false) { + return Some(Err(error_end_of_input())); } let slice; unsafe { - slice = std::slice::from_raw_parts( self.ptr, length ); - self.ptr = self.ptr.add( length ); + slice = std::slice::from_raw_parts(self.ptr, length); + self.ptr = self.ptr.add(length); } - Some( Ok( slice ) ) + Some(Ok(slice)) } #[inline(always)] - fn can_read_at_least( &self, size: usize ) -> Option< bool > { - Some( (self.end as usize - self.ptr as usize) >= size ) + fn can_read_at_least(&self, size: usize) -> Option { + Some((self.end as usize - self.ptr as usize) >= size) } #[inline(always)] - fn context( &self ) -> &C { + fn context(&self) -> &C { &self.context } #[inline(always)] - fn context_mut( &mut self ) -> &mut C { + fn context_mut(&mut self) -> &mut C { &mut self.context } } -struct StreamReader< C: Context, S: Read > { +struct StreamReader { context: C, reader: S, buffer: CircularBuffer, - is_buffering: bool + is_buffering: bool, } -impl< 'a, C, S > StreamReader< C, S > where C: Context, S: Read { +impl<'a, C, S> StreamReader +where + C: Context, + S: Read, +{ #[inline(never)] - fn read_bytes_slow( &mut self, mut output: &mut [u8] ) -> Result< (), C::Error > { + fn read_bytes_slow(&mut self, mut output: &mut [u8]) -> Result<(), C::Error> { if self.is_buffering && output.len() < self.buffer.capacity() { let reader = &mut self.reader; while self.buffer.len() < self.buffer.capacity() { - let bytes_written = self.buffer.try_append_with( self.buffer.capacity() - self.buffer.len(), |chunk| { - reader.read( chunk ) - }).map_err( |error| { - let error = Error::from_io_error( error ); - >::from( error ) - })?; + let bytes_written = self + .buffer + .try_append_with(self.buffer.capacity() - self.buffer.len(), |chunk| { + reader.read(chunk) + }) + .map_err(|error| { + let error = Error::from_io_error(error); + >::from(error) + })?; if bytes_written == 0 { if self.buffer.len() < output.len() { - return Err( error_end_of_input() ); + return Err(error_end_of_input()); } else { break; } @@ -315,98 +351,100 @@ impl< 'a, C, S > StreamReader< C, S > where C: Context, S: Read { } if self.buffer.len() > 0 { - let length = std::cmp::min( self.buffer.len(), output.len() ); - self.buffer.consume_into( &mut output[ ..length ] ); - output = &mut output[ length.. ]; + let length = std::cmp::min(self.buffer.len(), output.len()); + self.buffer.consume_into(&mut output[..length]); + output = &mut output[length..]; } if output.is_empty() { return Ok(()); } - self.reader.read_exact( output ).map_err( |error| { - let error = Error::from_io_error( error ); - >::from( error ) + self.reader.read_exact(output).map_err(|error| { + let error = Error::from_io_error(error); + >::from(error) }) } } -impl< 'a, C: Context, S: Read > Reader< 'a, C > for StreamReader< C, S > { +impl<'a, C: Context, S: Read> Reader<'a, C> for StreamReader { #[inline(always)] - fn read_bytes( &mut self, output: &mut [u8] ) -> Result< (), C::Error > { + fn read_bytes(&mut self, output: &mut [u8]) -> Result<(), C::Error> { if self.buffer.len() >= output.len() { - self.buffer.consume_into( output ); + self.buffer.consume_into(output); return Ok(()); } - self.read_bytes_slow( output ) + self.read_bytes_slow(output) } - fn peek_bytes( &mut self, output: &mut [u8] ) -> Result< (), C::Error > { + fn peek_bytes(&mut self, output: &mut [u8]) -> Result<(), C::Error> { if output.len() > self.buffer.len() { let reader = &mut self.reader; while self.buffer.len() < output.len() { let mut chunk_size = output.len() - self.buffer.len(); if self.is_buffering { - chunk_size = std::cmp::max( chunk_size, self.buffer.capacity() - self.buffer.len() ); + chunk_size = + std::cmp::max(chunk_size, self.buffer.capacity() - self.buffer.len()); } - let bytes_written = self.buffer.try_append_with( chunk_size, |chunk| { - reader.read( chunk ) - }).map_err( |error| { - let error = Error::from_io_error( error ); - >::from( error ) - })?; + let bytes_written = self + .buffer + .try_append_with(chunk_size, |chunk| reader.read(chunk)) + .map_err(|error| { + let error = Error::from_io_error(error); + >::from(error) + })?; if bytes_written == 0 { - return Err( error_end_of_input() ); + return Err(error_end_of_input()); } } } - let (a, b) = self.buffer.as_slices_of_length( output.len() ); - output[ ..a.len() ].copy_from_slice( a ); + let (a, b) = self.buffer.as_slices_of_length(output.len()); + output[..a.len()].copy_from_slice(a); - if let Some( b ) = b { - output[ a.len().. ].copy_from_slice( b ); + if let Some(b) = b { + output[a.len()..].copy_from_slice(b); } Ok(()) } #[inline(always)] - fn context( &self ) -> &C { + fn context(&self) -> &C { &self.context } #[inline(always)] - fn context_mut( &mut self ) -> &mut C { + fn context_mut(&mut self) -> &mut C { &mut self.context } } -impl< C: Context, S: Read > StreamReader< C, S > { +impl StreamReader { #[inline] - fn deserialize< 'a, T: Readable< 'a, C > >( context: C, reader: S, is_buffering: bool ) -> Result< T, C::Error > { - let capacity = if is_buffering { - 8 * 1024 - } else { - 0 - }; + fn deserialize<'a, T: Readable<'a, C>>( + context: C, + reader: S, + is_buffering: bool, + ) -> Result { + let capacity = if is_buffering { 8 * 1024 } else { 0 }; let mut reader = StreamReader { context, reader, - buffer: CircularBuffer::with_capacity( capacity ), - is_buffering + buffer: CircularBuffer::with_capacity(capacity), + is_buffering, }; - T::read_from( &mut reader ) + T::read_from(&mut reader) } } -pub trait Readable< 'a, C: Context >: Sized { - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error >; +pub trait Readable<'a, C: Context>: Sized { + fn read_from>(reader: &mut R) -> Result; #[inline] fn minimum_bytes_needed() -> usize { @@ -417,32 +455,48 @@ pub trait Readable< 'a, C: Context >: Sized { /// /// This performs zero-copy deserialization when possible. #[inline] - fn read_from_buffer( buffer: &'a [u8] ) -> Result< Self, C::Error > where Self: DefaultContext< Context = C >, C: Default { - Self::read_from_buffer_with_ctx( Default::default(), buffer ) + fn read_from_buffer(buffer: &'a [u8]) -> Result + where + Self: DefaultContext, + C: Default, + { + Self::read_from_buffer_with_ctx(Default::default(), buffer) } /// Deserializes from a given buffer while also returning the amount of bytes consumed. /// /// This performs zero-copy deserialization when possible. #[inline] - fn read_with_length_from_buffer( buffer: &'a [u8] ) -> (Result< Self, C::Error >, usize) where Self: DefaultContext< Context = C >, C: Default { - Self::read_with_length_from_buffer_with_ctx( Default::default(), buffer ) + fn read_with_length_from_buffer(buffer: &'a [u8]) -> (Result, usize) + where + Self: DefaultContext, + C: Default, + { + Self::read_with_length_from_buffer_with_ctx(Default::default(), buffer) } /// Deserializes from a given buffer. /// /// This never performs zero-copy deserialization. #[inline] - fn read_from_buffer_copying_data( buffer: &[u8] ) -> Result< Self, C::Error > where Self: DefaultContext< Context = C >, C: Default { - Self::read_from_buffer_copying_data_with_ctx( Default::default(), buffer ) + fn read_from_buffer_copying_data(buffer: &[u8]) -> Result + where + Self: DefaultContext, + C: Default, + { + Self::read_from_buffer_copying_data_with_ctx(Default::default(), buffer) } /// Deserializes from a given buffer while also returning the amount of bytes consumed. /// /// This never performs zero-copy deserialization. #[inline] - fn read_with_length_from_buffer_copying_data( buffer: &[u8] ) -> (Result< Self, C::Error >, usize) where Self: DefaultContext< Context = C >, C: Default { - Self::read_with_length_from_buffer_copying_data_with_ctx( Default::default(), buffer ) + fn read_with_length_from_buffer_copying_data(buffer: &[u8]) -> (Result, usize) + where + Self: DefaultContext, + C: Default, + { + Self::read_with_length_from_buffer_copying_data_with_ctx(Default::default(), buffer) } /// Reads from a given stream without any buffering. @@ -453,8 +507,12 @@ pub trait Readable< 'a, C: Context >: Sized { /// Use [`read_from_stream_buffered`](Readable::read_from_stream_buffered) if you need /// to read from a stream and you don't care about not overreading. #[inline] - fn read_from_stream_unbuffered( stream: impl Read ) -> Result< Self, C::Error > where Self: DefaultContext< Context = C >, C: Default { - Self::read_from_stream_unbuffered_with_ctx( Default::default(), stream ) + fn read_from_stream_unbuffered(stream: impl Read) -> Result + where + Self: DefaultContext, + C: Default, + { + Self::read_from_stream_unbuffered_with_ctx(Default::default(), stream) } /// Reads from a given stream with internal buffering. @@ -466,78 +524,107 @@ pub trait Readable< 'a, C: Context >: Sized { /// Use the slower [`read_from_stream_unbuffered`](Readable::read_from_stream_unbuffered) if you want /// to avoid overreading. #[inline] - fn read_from_stream_buffered( stream: impl Read ) -> Result< Self, C::Error > where Self: DefaultContext< Context = C >, C: Default { - Self::read_from_stream_buffered_with_ctx( Default::default(), stream ) + fn read_from_stream_buffered(stream: impl Read) -> Result + where + Self: DefaultContext, + C: Default, + { + Self::read_from_stream_buffered_with_ctx(Default::default(), stream) } #[inline] - fn read_from_file( path: impl AsRef< Path > ) -> Result< Self, C::Error > where Self: DefaultContext< Context = C >, C: Default { - Self::read_from_file_with_ctx( Default::default(), path ) + fn read_from_file(path: impl AsRef) -> Result + where + Self: DefaultContext, + C: Default, + { + Self::read_from_file_with_ctx(Default::default(), path) } #[inline] - fn read_from_buffer_with_ctx( context: C, buffer: &'a [u8] ) -> Result< Self, C::Error > { - Self::read_with_length_from_buffer_with_ctx( context, buffer ).0 + fn read_from_buffer_with_ctx(context: C, buffer: &'a [u8]) -> Result { + Self::read_with_length_from_buffer_with_ctx(context, buffer).0 } #[inline] - fn read_with_length_from_buffer_with_ctx( context: C, buffer: &'a [u8] ) -> (Result< Self, C::Error >, usize) { + fn read_with_length_from_buffer_with_ctx( + context: C, + buffer: &'a [u8], + ) -> (Result, usize) { let bytes_needed = Self::minimum_bytes_needed(); let buffer_length = buffer.len(); if buffer_length < bytes_needed { - return (Err( error_input_buffer_is_too_small( buffer_length, bytes_needed ) ), 0); + return ( + Err(error_input_buffer_is_too_small(buffer_length, bytes_needed)), + 0, + ); } - let mut reader = BufferReader::new( context, buffer ); - let value = Self::read_from( &mut reader ); + let mut reader = BufferReader::new(context, buffer); + let value = Self::read_from(&mut reader); let bytes_read = reader.ptr as usize - buffer.as_ptr() as usize; (value, bytes_read) } #[inline] - fn read_from_buffer_copying_data_with_ctx( context: C, buffer: &[u8] ) -> Result< Self, C::Error > { - Self::read_with_length_from_buffer_copying_data_with_ctx( context, buffer ).0 + fn read_from_buffer_copying_data_with_ctx(context: C, buffer: &[u8]) -> Result { + Self::read_with_length_from_buffer_copying_data_with_ctx(context, buffer).0 } #[inline] - fn read_with_length_from_buffer_copying_data_with_ctx( mut context: C, buffer: &[u8] ) -> (Result< Self, C::Error >, usize) { - Self::read_with_length_from_buffer_copying_data_with_ctx_mut( &mut context, buffer ) + fn read_with_length_from_buffer_copying_data_with_ctx( + mut context: C, + buffer: &[u8], + ) -> (Result, usize) { + Self::read_with_length_from_buffer_copying_data_with_ctx_mut(&mut context, buffer) } #[inline] - fn read_with_length_from_buffer_copying_data_with_ctx_mut( context: &mut C, buffer: &[u8] ) -> (Result< Self, C::Error >, usize) { + fn read_with_length_from_buffer_copying_data_with_ctx_mut( + context: &mut C, + buffer: &[u8], + ) -> (Result, usize) { let bytes_needed = Self::minimum_bytes_needed(); let buffer_length = buffer.len(); if buffer_length < bytes_needed { - return (Err( error_input_buffer_is_too_small( buffer_length, bytes_needed ) ), 0); + return ( + Err(error_input_buffer_is_too_small(buffer_length, bytes_needed)), + 0, + ); } - let mut reader = CopyingBufferReader::new( context, buffer ); - let value = Self::read_from( &mut reader ); + let mut reader = CopyingBufferReader::new(context, buffer); + let value = Self::read_from(&mut reader); let bytes_read = reader.ptr as usize - buffer.as_ptr() as usize; (value, bytes_read) } #[inline] - fn read_from_stream_unbuffered_with_ctx< S: Read >( context: C, stream: S ) -> Result< Self, C::Error > { - StreamReader::deserialize( context, stream, false ) + fn read_from_stream_unbuffered_with_ctx( + context: C, + stream: S, + ) -> Result { + StreamReader::deserialize(context, stream, false) } #[inline] - fn read_from_stream_buffered_with_ctx< S: Read >( context: C, stream: S ) -> Result< Self, C::Error > { - StreamReader::deserialize( context, stream, true ) + fn read_from_stream_buffered_with_ctx( + context: C, + stream: S, + ) -> Result { + StreamReader::deserialize(context, stream, true) } #[inline] - fn read_from_file_with_ctx( context: C, path: impl AsRef< Path > ) -> Result< Self, C::Error > { - let stream = File::open( path ).map_err( |error| { - let error = Error::from_io_error( error ); - >::from( error ) + fn read_from_file_with_ctx(context: C, path: impl AsRef) -> Result { + let stream = File::open(path).map_err(|error| { + let error = Error::from_io_error(error); + >::from(error) })?; #[cfg(not(all(target_os = "linux", target_arch = "x86_64")))] { - Self::read_from_stream_buffered_with_ctx( context, stream ) + Self::read_from_stream_buffered_with_ctx(context, stream) } #[cfg(all(target_os = "linux", target_arch = "x86_64"))] @@ -552,19 +639,12 @@ pub trait Readable< 'a, C: Context >: Sized { prot: i32, flags: i32, fd: i32, - offset: i64 + offset: i64, ) -> *mut std::ffi::c_void; - fn madvise( - addr: *mut std::ffi::c_void, - len: usize, - advice: i32 - ) -> i32; + fn madvise(addr: *mut std::ffi::c_void, len: usize, advice: i32) -> i32; - fn munmap( - addr: *mut std::ffi::c_void, - len: usize - ) -> i32; + fn munmap(addr: *mut std::ffi::c_void, len: usize) -> i32; } const MAP_PRIVATE: i32 = 0x0002; @@ -574,34 +654,43 @@ pub trait Readable< 'a, C: Context >: Sized { const MADV_WILLNEED: i32 = 3; static EMPTY: &[u8] = &[]; - struct Mmap( *mut std::ffi::c_void, usize ); + struct Mmap(*mut std::ffi::c_void, usize); impl Mmap { - fn open( fp: &std::fs::File ) -> Result< Self, Error > { - let size = fp.metadata().map_err( Error::from_io_error )?.len(); + fn open(fp: &std::fs::File) -> Result { + let size = fp.metadata().map_err(Error::from_io_error)?.len(); if size > std::usize::MAX as u64 { - return Err( crate::error::error_too_big_usize_for_this_architecture() ); + return Err(crate::error::error_too_big_usize_for_this_architecture()); } if size == 0 { - return Ok( Mmap( EMPTY.as_ptr() as _, 0 ) ); + return Ok(Mmap(EMPTY.as_ptr() as _, 0)); } let size = size as usize; - let pointer = unsafe { mmap( std::ptr::null_mut(), size, PROT_READ, MAP_PRIVATE, fp.as_raw_fd(), 0 ) }; + let pointer = unsafe { + mmap( + std::ptr::null_mut(), + size, + PROT_READ, + MAP_PRIVATE, + fp.as_raw_fd(), + 0, + ) + }; if pointer == MAP_FAILED { - Err( Error::from_io_error( std::io::Error::last_os_error() ) ) + Err(Error::from_io_error(std::io::Error::last_os_error())) } else { - Ok( Mmap( pointer, size ) ) + Ok(Mmap(pointer, size)) } } - unsafe fn madvise( &mut self, advice: i32 ) -> Result< (), Error > { + unsafe fn madvise(&mut self, advice: i32) -> Result<(), Error> { if self.1 == 0 { return Ok(()); } - if madvise( self.0, self.1, advice ) < 0 { - Err( Error::from_io_error( std::io::Error::last_os_error() ) ) + if madvise(self.0, self.1, advice) < 0 { + Err(Error::from_io_error(std::io::Error::last_os_error())) } else { Ok(()) } @@ -611,30 +700,28 @@ pub trait Readable< 'a, C: Context >: Sized { impl std::ops::Deref for Mmap { type Target = [u8]; #[inline] - fn deref( &self ) -> &Self::Target { - unsafe { - std::slice::from_raw_parts( self.0.cast::< u8 >(), self.1 ) - } + fn deref(&self) -> &Self::Target { + unsafe { std::slice::from_raw_parts(self.0.cast::(), self.1) } } } impl Drop for Mmap { - fn drop( &mut self ) { + fn drop(&mut self) { if self.1 != 0 { unsafe { - munmap( self.0, self.1 ); + munmap(self.0, self.1); } } } } - let mut mmap = Mmap::open( &stream )?; + let mut mmap = Mmap::open(&stream)?; unsafe { - mmap.madvise( MADV_SEQUENTIAL )?; - mmap.madvise( MADV_WILLNEED )?; + mmap.madvise(MADV_SEQUENTIAL)?; + mmap.madvise(MADV_WILLNEED)?; } - Self::read_from_buffer_copying_data_with_ctx( context, &mmap ) + Self::read_from_buffer_copying_data_with_ctx(context, &mmap) } } @@ -647,19 +734,19 @@ pub trait Readable< 'a, C: Context >: Sized { #[doc(hidden)] #[inline] - unsafe fn speedy_slice_from_bytes( _: &[u8] ) -> &[Self] { + unsafe fn speedy_slice_from_bytes(_: &[u8]) -> &[Self] { panic!(); } #[doc(hidden)] #[inline] - unsafe fn speedy_flip_endianness( _: *mut Self ) { + unsafe fn speedy_flip_endianness(_: *mut Self) { panic!(); } #[doc(hidden)] #[inline] - fn speedy_convert_slice_endianness( _: Endianness, _: &mut [Self] ) { + fn speedy_convert_slice_endianness(_: Endianness, _: &mut [Self]) { panic!() } } @@ -667,38 +754,36 @@ pub trait Readable< 'a, C: Context >: Sized { #[test] fn test_peek() { let value: &[f64] = &[2.0, 123.0]; - let data = unsafe { - std::slice::from_raw_parts( value.as_ptr() as *const u8, 16 ) - }; + let data = unsafe { std::slice::from_raw_parts(value.as_ptr() as *const u8, 16) }; let mut ctx = crate::LittleEndian {}; macro_rules! test { ($peek:ident, $read:ident) => { - let mut reader = CopyingBufferReader::new( &mut ctx, data ); + let mut reader = CopyingBufferReader::new(&mut ctx, data); let value = reader.$peek().unwrap(); for _ in 0..8 { - assert_eq!( value, reader.$peek().unwrap() ); + assert_eq!(value, reader.$peek().unwrap()); } - assert_eq!( value, reader.$read().unwrap() ); - } + assert_eq!(value, reader.$read().unwrap()); + }; } - test!( peek_f64, read_f64 ); - test!( peek_f32, read_f32 ); - test!( peek_u128, read_u128 ); - test!( peek_u64, read_u64 ); - test!( peek_u32, read_u32 ); - test!( peek_u16, read_u16 ); - test!( peek_u8, read_u8 ); - test!( peek_i128, read_i128 ); - test!( peek_i64, read_i64 ); - test!( peek_i32, read_i32 ); - test!( peek_i16, read_i16 ); - test!( peek_i8, read_i8 ); - test!( peek_u64_varint, read_u64_varint ); - - let mut reader = CopyingBufferReader::new( &mut ctx, data ); + test!(peek_f64, read_f64); + test!(peek_f32, read_f32); + test!(peek_u128, read_u128); + test!(peek_u64, read_u64); + test!(peek_u32, read_u32); + test!(peek_u16, read_u16); + test!(peek_u8, read_u8); + test!(peek_i128, read_i128); + test!(peek_i64, read_i64); + test!(peek_i32, read_i32); + test!(peek_i16, read_i16); + test!(peek_i8, read_i8); + test!(peek_u64_varint, read_u64_varint); + + let mut reader = CopyingBufferReader::new(&mut ctx, data); reader.peek_u8().unwrap(); - assert_eq!( reader.read_f64().unwrap(), 2.0 ); + assert_eq!(reader.read_f64().unwrap(), 2.0); } diff --git a/src/readable_impl.rs b/src/readable_impl.rs index 23de718..f3d8256 100644 --- a/src/readable_impl.rs +++ b/src/readable_impl.rs @@ -1,25 +1,26 @@ -use std::mem; use std::borrow::{Cow, ToOwned}; -use std::ops::Range; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::hash::{BuildHasher, Hash}; +use std::mem; +use std::ops::Range; use crate::readable::Readable; use crate::reader::Reader; use crate::context::Context; -use crate::utils::SwapBytes; use crate::endianness::Endianness; +use crate::utils::SwapBytes; -impl< 'a, C, K, V > Readable< 'a, C > for BTreeMap< K, V > - where C: Context, - K: Readable< 'a, C > + Ord, - V: Readable< 'a, C >, +impl<'a, C, K, V> Readable<'a, C> for BTreeMap +where + C: Context, + K: Readable<'a, C> + Ord, + V: Readable<'a, C>, { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - let length = crate::private::read_length( reader )?; - reader.read_key_value_collection( length ) + fn read_from>(reader: &mut R) -> Result { + let length = crate::private::read_length(reader)?; + reader.read_key_value_collection(length) } #[inline] @@ -28,14 +29,15 @@ impl< 'a, C, K, V > Readable< 'a, C > for BTreeMap< K, V > } } -impl< 'a, C, T > Readable< 'a, C > for BTreeSet< T > - where C: Context, - T: Readable< 'a, C > + Ord +impl<'a, C, T> Readable<'a, C> for BTreeSet +where + C: Context, + T: Readable<'a, C> + Ord, { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - let length = crate::private::read_length( reader )?; - reader.read_collection( length ) + fn read_from>(reader: &mut R) -> Result { + let length = crate::private::read_length(reader)?; + reader.read_collection(length) } #[inline] @@ -44,16 +46,17 @@ impl< 'a, C, T > Readable< 'a, C > for BTreeSet< T > } } -impl< 'a, C, K, V, S > Readable< 'a, C > for HashMap< K, V, S > - where C: Context, - K: Readable< 'a, C > + Eq + Hash, - V: Readable< 'a, C >, - S: BuildHasher + Default +impl<'a, C, K, V, S> Readable<'a, C> for HashMap +where + C: Context, + K: Readable<'a, C> + Eq + Hash, + V: Readable<'a, C>, + S: BuildHasher + Default, { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - let length = crate::private::read_length( reader )?; - reader.read_key_value_collection( length ) + fn read_from>(reader: &mut R) -> Result { + let length = crate::private::read_length(reader)?; + reader.read_key_value_collection(length) } #[inline] @@ -62,15 +65,16 @@ impl< 'a, C, K, V, S > Readable< 'a, C > for HashMap< K, V, S > } } -impl< 'a, C, T, S > Readable< 'a, C > for HashSet< T, S > - where C: Context, - T: Readable< 'a, C > + Eq + Hash, - S: BuildHasher + Default +impl<'a, C, T, S> Readable<'a, C> for HashSet +where + C: Context, + T: Readable<'a, C> + Eq + Hash, + S: BuildHasher + Default, { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - let length = crate::private::read_length( reader )?; - reader.read_collection( length ) + fn read_from>(reader: &mut R) -> Result { + let length = crate::private::read_length(reader)?; + reader.read_collection(length) } #[inline] @@ -79,14 +83,14 @@ impl< 'a, C, T, S > Readable< 'a, C > for HashSet< T, S > } } -impl< 'a, C: Context > Readable< 'a, C > for bool { +impl<'a, C: Context> Readable<'a, C> for bool { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { + fn read_from>(reader: &mut R) -> Result { let value = reader.read_u8()?; if value == 0 { - Ok( false ) + Ok(false) } else { - Ok( true ) + Ok(true) } } @@ -96,11 +100,11 @@ impl< 'a, C: Context > Readable< 'a, C > for bool { } } -impl< 'a, C: Context > Readable< 'a, C > for char { +impl<'a, C: Context> Readable<'a, C> for char { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { + fn read_from>(reader: &mut R) -> Result { let value = reader.read_u32()?; - std::char::from_u32( value ).ok_or_else( crate::error::error_out_of_range_char ) + std::char::from_u32(value).ok_or_else(crate::error::error_out_of_range_char) } #[inline] @@ -111,15 +115,15 @@ impl< 'a, C: Context > Readable< 'a, C > for char { macro_rules! impl_for_primitive { ($type:ty, $getter:ident, $endianness_swap:ident) => { - impl< 'a, C: Context > Readable< 'a, C > for $type { + impl<'a, C: Context> Readable<'a, C> for $type { #[inline(always)] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { + fn read_from>(reader: &mut R) -> Result { reader.$getter() } #[inline] fn minimum_bytes_needed() -> usize { - mem::size_of::< Self >() + mem::size_of::() } #[doc(hidden)] @@ -130,92 +134,98 @@ macro_rules! impl_for_primitive { #[doc(hidden)] #[inline] - unsafe fn speedy_slice_from_bytes( slice: &[u8] ) -> &[Self] { + unsafe fn speedy_slice_from_bytes(slice: &[u8]) -> &[Self] { unsafe { - std::slice::from_raw_parts( slice.as_ptr() as *const $type, slice.len() / mem::size_of::< Self >() ) + std::slice::from_raw_parts( + slice.as_ptr() as *const $type, + slice.len() / mem::size_of::(), + ) } } #[doc(hidden)] #[inline(always)] - unsafe fn speedy_flip_endianness( itself: *mut Self ) { + unsafe fn speedy_flip_endianness(itself: *mut Self) { unsafe { - std::ptr::write_unaligned( itself, std::ptr::read_unaligned( itself ).swap_bytes() ); + std::ptr::write_unaligned( + itself, + std::ptr::read_unaligned(itself).swap_bytes(), + ); } } #[doc(hidden)] #[inline(always)] - fn speedy_convert_slice_endianness( endianness: Endianness, slice: &mut [$type] ) { - endianness.$endianness_swap( slice ); + fn speedy_convert_slice_endianness(endianness: Endianness, slice: &mut [$type]) { + endianness.$endianness_swap(slice); } } - } -} - -impl_for_primitive!( i8, read_i8, swap_slice_i8 ); -impl_for_primitive!( i16, read_i16, swap_slice_i16 ); -impl_for_primitive!( i32, read_i32, swap_slice_i32 ); -impl_for_primitive!( i64, read_i64, swap_slice_i64 ); -impl_for_primitive!( i128, read_i128, swap_slice_i128 ); -impl_for_primitive!( u8, read_u8, swap_slice_u8 ); -impl_for_primitive!( u16, read_u16, swap_slice_u16 ); -impl_for_primitive!( u32, read_u32, swap_slice_u32 ); -impl_for_primitive!( u64, read_u64, swap_slice_u64 ); -impl_for_primitive!( u128, read_u128, swap_slice_u128 ); -impl_for_primitive!( f32, read_f32, swap_slice_f32 ); -impl_for_primitive!( f64, read_f64, swap_slice_f64 ); - -impl< 'a, C: Context > Readable< 'a, C > for usize { - #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - let value = u64::read_from( reader )?; + }; +} + +impl_for_primitive!(i8, read_i8, swap_slice_i8); +impl_for_primitive!(i16, read_i16, swap_slice_i16); +impl_for_primitive!(i32, read_i32, swap_slice_i32); +impl_for_primitive!(i64, read_i64, swap_slice_i64); +impl_for_primitive!(i128, read_i128, swap_slice_i128); +impl_for_primitive!(u8, read_u8, swap_slice_u8); +impl_for_primitive!(u16, read_u16, swap_slice_u16); +impl_for_primitive!(u32, read_u32, swap_slice_u32); +impl_for_primitive!(u64, read_u64, swap_slice_u64); +impl_for_primitive!(u128, read_u128, swap_slice_u128); +impl_for_primitive!(f32, read_f32, swap_slice_f32); +impl_for_primitive!(f64, read_f64, swap_slice_f64); + +impl<'a, C: Context> Readable<'a, C> for usize { + #[inline] + fn read_from>(reader: &mut R) -> Result { + let value = u64::read_from(reader)?; if value > std::usize::MAX as u64 { - return Err( crate::error::error_too_big_usize_for_this_architecture() ); + return Err(crate::error::error_too_big_usize_for_this_architecture()); } - Ok( value as usize ) + Ok(value as usize) } #[inline] fn minimum_bytes_needed() -> usize { - >::minimum_bytes_needed() + >::minimum_bytes_needed() } } -impl< 'a, C: Context > Readable< 'a, C > for String { +impl<'a, C: Context> Readable<'a, C> for String { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - let bytes: Vec< u8 > = reader.read_value()?; - let value = crate::private::vec_to_string( bytes )?; - Ok( value ) + fn read_from>(reader: &mut R) -> Result { + let bytes: Vec = reader.read_value()?; + let value = crate::private::vec_to_string(bytes)?; + Ok(value) } #[inline] fn minimum_bytes_needed() -> usize { - as Readable< 'a, C >>::minimum_bytes_needed() + as Readable<'a, C>>::minimum_bytes_needed() } } -impl< 'a, C: Context > Readable< 'a, C > for Cow< 'a, str > { +impl<'a, C: Context> Readable<'a, C> for Cow<'a, str> { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - let length = crate::private::read_length( reader )?; - let bytes: Cow< 'a, [u8] > = reader.read_cow( length )?; - let value = crate::private::cow_bytes_to_cow_str( bytes )?; - Ok( value ) + fn read_from>(reader: &mut R) -> Result { + let length = crate::private::read_length(reader)?; + let bytes: Cow<'a, [u8]> = reader.read_cow(length)?; + let value = crate::private::cow_bytes_to_cow_str(bytes)?; + Ok(value) } #[inline] fn minimum_bytes_needed() -> usize { - >::minimum_bytes_needed() + >::minimum_bytes_needed() } } -impl< 'a, C: Context, T: Readable< 'a, C > > Readable< 'a, C > for Vec< T > { +impl<'a, C: Context, T: Readable<'a, C>> Readable<'a, C> for Vec { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - let length = crate::private::read_length( reader )?; - reader.read_vec( length ) + fn read_from>(reader: &mut R) -> Result { + let length = crate::private::read_length(reader)?; + reader.read_vec(length) } #[inline] @@ -224,92 +234,111 @@ impl< 'a, C: Context, T: Readable< 'a, C > > Readable< 'a, C > for Vec< T > { } } -impl< 'a, C: Context, T: Readable< 'a, C > > Readable< 'a, C > for Cow< 'a, [T] > where [T]: ToOwned< Owned = Vec< T > > { +impl<'a, C: Context, T: Readable<'a, C>> Readable<'a, C> for Cow<'a, [T]> +where + [T]: ToOwned>, +{ #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - let length = crate::private::read_length( reader )?; - reader.read_cow( length ) + fn read_from>(reader: &mut R) -> Result { + let length = crate::private::read_length(reader)?; + reader.read_cow(length) } #[inline] fn minimum_bytes_needed() -> usize { - as Readable< 'a, C >>::minimum_bytes_needed() + as Readable<'a, C>>::minimum_bytes_needed() } } -impl< 'a, C: Context, T: Readable< 'a, C > > Readable< 'a, C > for Cow< 'a, HashSet< T > > where T: Readable< 'a, C > + Clone + Hash + Eq { +impl<'a, C: Context, T: Readable<'a, C>> Readable<'a, C> for Cow<'a, HashSet> +where + T: Readable<'a, C> + Clone + Hash + Eq, +{ #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - Ok( Cow::Owned( reader.read_value()? ) ) + fn read_from>(reader: &mut R) -> Result { + Ok(Cow::Owned(reader.read_value()?)) } #[inline] fn minimum_bytes_needed() -> usize { - as Readable< 'a, C >>::minimum_bytes_needed() + as Readable<'a, C>>::minimum_bytes_needed() } } -impl< 'a, C: Context, T: Readable< 'a, C > > Readable< 'a, C > for Cow< 'a, BTreeSet< T > > where T: Readable< 'a, C > + Clone + Ord { +impl<'a, C: Context, T: Readable<'a, C>> Readable<'a, C> for Cow<'a, BTreeSet> +where + T: Readable<'a, C> + Clone + Ord, +{ #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - Ok( Cow::Owned( reader.read_value()? ) ) + fn read_from>(reader: &mut R) -> Result { + Ok(Cow::Owned(reader.read_value()?)) } #[inline] fn minimum_bytes_needed() -> usize { - as Readable< 'a, C >>::minimum_bytes_needed() + as Readable<'a, C>>::minimum_bytes_needed() } } -impl< 'a, C: Context, K: Readable< 'a, C >, V: Readable< 'a, C > > Readable< 'a, C > for Cow< 'a, HashMap< K, V > > where K: Readable< 'a, C > + Clone + Hash + Eq, V: Readable< 'a, C > + Clone { +impl<'a, C: Context, K: Readable<'a, C>, V: Readable<'a, C>> Readable<'a, C> + for Cow<'a, HashMap> +where + K: Readable<'a, C> + Clone + Hash + Eq, + V: Readable<'a, C> + Clone, +{ #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - Ok( Cow::Owned( reader.read_value()? ) ) + fn read_from>(reader: &mut R) -> Result { + Ok(Cow::Owned(reader.read_value()?)) } #[inline] fn minimum_bytes_needed() -> usize { - as Readable< 'a, C >>::minimum_bytes_needed() + as Readable<'a, C>>::minimum_bytes_needed() } } -impl< 'a, C: Context, K: Readable< 'a, C >, V: Readable< 'a, C > > Readable< 'a, C > for Cow< 'a, BTreeMap< K, V > > where K: Readable< 'a, C > + Clone + Ord, V: Readable< 'a, C > + Clone { +impl<'a, C: Context, K: Readable<'a, C>, V: Readable<'a, C>> Readable<'a, C> + for Cow<'a, BTreeMap> +where + K: Readable<'a, C> + Clone + Ord, + V: Readable<'a, C> + Clone, +{ #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - Ok( Cow::Owned( reader.read_value()? ) ) + fn read_from>(reader: &mut R) -> Result { + Ok(Cow::Owned(reader.read_value()?)) } #[inline] fn minimum_bytes_needed() -> usize { - as Readable< 'a, C >>::minimum_bytes_needed() + as Readable<'a, C>>::minimum_bytes_needed() } } -impl< 'a, C: Context, T: Readable< 'a, C > > Readable< 'a, C > for Range< T > { +impl<'a, C: Context, T: Readable<'a, C>> Readable<'a, C> for Range { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { + fn read_from>(reader: &mut R) -> Result { let start = reader.read_value()?; let end = reader.read_value()?; - Ok( start..end ) + Ok(start..end) } #[inline] fn minimum_bytes_needed() -> usize { - >::minimum_bytes_needed() * 2 + >::minimum_bytes_needed() * 2 } } -impl< 'a, C: Context, T: Readable< 'a, C > > Readable< 'a, C > for Option< T > { +impl<'a, C: Context, T: Readable<'a, C>> Readable<'a, C> for Option { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { + fn read_from>(reader: &mut R) -> Result { let flag = reader.read_value()?; let value = if flag { - Some( reader.read_value()? ) + Some(reader.read_value()?) } else { None }; - Ok( value ) + Ok(value) } #[inline] @@ -318,9 +347,9 @@ impl< 'a, C: Context, T: Readable< 'a, C > > Readable< 'a, C > for Option< T > { } } -impl< 'a, C: Context > Readable< 'a, C > for () { +impl<'a, C: Context> Readable<'a, C> for () { #[inline] - fn read_from< R: Reader< 'a, C > >( _: &mut R ) -> Result< Self, C::Error > { + fn read_from>(_: &mut R) -> Result { Ok(()) } @@ -355,26 +384,26 @@ macro_rules! impl_for_tuple { } } -impl_for_tuple!( A0 ); -impl_for_tuple!( A0, A1 ); -impl_for_tuple!( A0, A1, A2 ); -impl_for_tuple!( A0, A1, A2, A3 ); -impl_for_tuple!( A0, A1, A2, A3, A4 ); -impl_for_tuple!( A0, A1, A2, A3, A4, A5 ); -impl_for_tuple!( A0, A1, A2, A3, A4, A5, A6 ); -impl_for_tuple!( A0, A1, A2, A3, A4, A5, A6, A7 ); -impl_for_tuple!( A0, A1, A2, A3, A4, A5, A6, A7, A8 ); -impl_for_tuple!( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9 ); -impl_for_tuple!( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 ); +impl_for_tuple!(A0); +impl_for_tuple!(A0, A1); +impl_for_tuple!(A0, A1, A2); +impl_for_tuple!(A0, A1, A2, A3); +impl_for_tuple!(A0, A1, A2, A3, A4); +impl_for_tuple!(A0, A1, A2, A3, A4, A5); +impl_for_tuple!(A0, A1, A2, A3, A4, A5, A6); +impl_for_tuple!(A0, A1, A2, A3, A4, A5, A6, A7); +impl_for_tuple!(A0, A1, A2, A3, A4, A5, A6, A7, A8); +impl_for_tuple!(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9); +impl_for_tuple!(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); -impl< 'a, C: Context > Readable< 'a, C > for Endianness { +impl<'a, C: Context> Readable<'a, C> for Endianness { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { + fn read_from>(reader: &mut R) -> Result { let value = reader.read_u8()?; match value { - 0 => Ok( Endianness::LittleEndian ), - 1 => Ok( Endianness::BigEndian ), - _ => Err( crate::error::error_invalid_enum_variant() ) + 0 => Ok(Endianness::LittleEndian), + 1 => Ok(Endianness::BigEndian), + _ => Err(crate::error::error_invalid_enum_variant()), } } @@ -386,62 +415,65 @@ impl< 'a, C: Context > Readable< 'a, C > for Endianness { macro_rules! impl_for_non_zero { ($type:ident, $base_type:ty) => { - impl< 'a, C: Context > Readable< 'a, C > for std::num::$type { + impl<'a, C: Context> Readable<'a, C> for std::num::$type { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { + fn read_from>(reader: &mut R) -> Result { let value: $base_type = reader.read_value()?; - std::num::$type::new( value ).ok_or_else( crate::error::error_zero_non_zero ) + std::num::$type::new(value).ok_or_else(crate::error::error_zero_non_zero) } #[inline] fn minimum_bytes_needed() -> usize { - mem::size_of::< $base_type >() + mem::size_of::<$base_type>() } } - } + }; } -impl_for_non_zero!( NonZeroU8, u8 ); -impl_for_non_zero!( NonZeroU16, u16 ); -impl_for_non_zero!( NonZeroU32, u32 ); -impl_for_non_zero!( NonZeroU64, u64 ); -impl_for_non_zero!( NonZeroI8, i8 ); -impl_for_non_zero!( NonZeroI16, i16 ); -impl_for_non_zero!( NonZeroI32, i32 ); -impl_for_non_zero!( NonZeroI64, i64 ); +impl_for_non_zero!(NonZeroU8, u8); +impl_for_non_zero!(NonZeroU16, u16); +impl_for_non_zero!(NonZeroU32, u32); +impl_for_non_zero!(NonZeroU64, u64); +impl_for_non_zero!(NonZeroI8, i8); +impl_for_non_zero!(NonZeroI16, i16); +impl_for_non_zero!(NonZeroI32, i32); +impl_for_non_zero!(NonZeroI64, i64); macro_rules! impl_for_atomic { ($type:ident, $base_type:ty) => { - impl< 'a, C: Context > Readable< 'a, C > for std::sync::atomic::$type { + impl<'a, C: Context> Readable<'a, C> for std::sync::atomic::$type { #[inline(always)] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { + fn read_from>(reader: &mut R) -> Result { let value: $base_type = reader.read_value()?; - Ok( value.into() ) + Ok(value.into()) } #[inline] fn minimum_bytes_needed() -> usize { - mem::size_of::< $base_type >() + mem::size_of::<$base_type>() } } - } + }; } -impl_for_atomic!( AtomicI8, i8 ); -impl_for_atomic!( AtomicI16, i16 ); -impl_for_atomic!( AtomicI32, i32 ); -impl_for_atomic!( AtomicI64, i64 ); +impl_for_atomic!(AtomicI8, i8); +impl_for_atomic!(AtomicI16, i16); +impl_for_atomic!(AtomicI32, i32); +impl_for_atomic!(AtomicI64, i64); -impl_for_atomic!( AtomicU8, u8 ); -impl_for_atomic!( AtomicU16, u16 ); -impl_for_atomic!( AtomicU32, u32 ); -impl_for_atomic!( AtomicU64, u64 ); +impl_for_atomic!(AtomicU8, u8); +impl_for_atomic!(AtomicU16, u16); +impl_for_atomic!(AtomicU32, u32); +impl_for_atomic!(AtomicU64, u64); -impl< 'a, C > Readable< 'a, C > for std::net::Ipv4Addr where C: Context { +impl<'a, C> Readable<'a, C> for std::net::Ipv4Addr +where + C: Context, +{ #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { + fn read_from>(reader: &mut R) -> Result { let value = reader.read_u32()?; - Ok( value.into() ) + Ok(value.into()) } #[inline] @@ -450,16 +482,19 @@ impl< 'a, C > Readable< 'a, C > for std::net::Ipv4Addr where C: Context { } } -impl< 'a, C > Readable< 'a, C > for std::net::Ipv6Addr where C: Context { +impl<'a, C> Readable<'a, C> for std::net::Ipv6Addr +where + C: Context, +{ #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { + fn read_from>(reader: &mut R) -> Result { let mut octets = [0; 16]; - reader.read_bytes( &mut octets )?; + reader.read_bytes(&mut octets)?; if !reader.endianness().conversion_necessary() { octets.reverse(); } - Ok( octets.into() ) + Ok(octets.into()) } #[inline] @@ -468,14 +503,17 @@ impl< 'a, C > Readable< 'a, C > for std::net::Ipv6Addr where C: Context { } } -impl< 'a, C > Readable< 'a, C > for std::net::IpAddr where C: Context { +impl<'a, C> Readable<'a, C> for std::net::IpAddr +where + C: Context, +{ #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { + fn read_from>(reader: &mut R) -> Result { let kind = reader.read_u8()?; match kind { - 0 => Ok( std::net::IpAddr::V4( reader.read_value()? ) ), - 1 => Ok( std::net::IpAddr::V6( reader.read_value()? ) ), - _ => Err( crate::error::error_invalid_enum_variant() ) + 0 => Ok(std::net::IpAddr::V4(reader.read_value()?)), + 1 => Ok(std::net::IpAddr::V6(reader.read_value()?)), + _ => Err(crate::error::error_invalid_enum_variant()), } } @@ -485,12 +523,15 @@ impl< 'a, C > Readable< 'a, C > for std::net::IpAddr where C: Context { } } -impl< 'a, C > Readable< 'a, C > for std::time::Duration where C: Context { +impl<'a, C> Readable<'a, C> for std::time::Duration +where + C: Context, +{ #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { + fn read_from>(reader: &mut R) -> Result { let secs = reader.read_u64()?; let nanos = reader.read_u32()?; - Ok( std::time::Duration::new( secs, nanos ) ) + Ok(std::time::Duration::new(secs, nanos)) } #[inline] @@ -499,11 +540,16 @@ impl< 'a, C > Readable< 'a, C > for std::time::Duration where C: Context { } } -impl< 'a, C > Readable< 'a, C > for std::time::SystemTime where C: Context { +impl<'a, C> Readable<'a, C> for std::time::SystemTime +where + C: Context, +{ #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - let duration = std::time::Duration::read_from( reader )?; - std::time::SystemTime::UNIX_EPOCH.checked_add( duration ).ok_or_else( crate::error::error_invalid_system_time ) + fn read_from>(reader: &mut R) -> Result { + let duration = std::time::Duration::read_from(reader)?; + std::time::SystemTime::UNIX_EPOCH + .checked_add(duration) + .ok_or_else(crate::error::error_invalid_system_time) } #[inline] @@ -513,31 +559,90 @@ impl< 'a, C > Readable< 'a, C > for std::time::SystemTime where C: Context { } macro_rules! repeat { - (1, $expr:expr) => { [$expr] }; - (2, $expr:expr) => { [$expr, $expr] }; - (3, $expr:expr) => { [$expr, $expr, $expr] }; - (4, $expr:expr) => { [$expr, $expr, $expr, $expr] }; - (5, $expr:expr) => { [$expr, $expr, $expr, $expr, $expr] }; - (6, $expr:expr) => { [$expr, $expr, $expr, $expr, $expr, $expr] }; - (7, $expr:expr) => { [$expr, $expr, $expr, $expr, $expr, $expr, $expr] }; - (8, $expr:expr) => { [$expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr] }; - (9, $expr:expr) => { [$expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr] }; - (10, $expr:expr) => { [$expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr] }; - (11, $expr:expr) => { [$expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr] }; - (12, $expr:expr) => { [$expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr] }; - (13, $expr:expr) => { [$expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr] }; - (14, $expr:expr) => { [$expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr] }; - (15, $expr:expr) => { [$expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr] }; - (16, $expr:expr) => { [$expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr] }; + (1, $expr:expr) => { + [$expr] + }; + (2, $expr:expr) => { + [$expr, $expr] + }; + (3, $expr:expr) => { + [$expr, $expr, $expr] + }; + (4, $expr:expr) => { + [$expr, $expr, $expr, $expr] + }; + (5, $expr:expr) => { + [$expr, $expr, $expr, $expr, $expr] + }; + (6, $expr:expr) => { + [$expr, $expr, $expr, $expr, $expr, $expr] + }; + (7, $expr:expr) => { + [$expr, $expr, $expr, $expr, $expr, $expr, $expr] + }; + (8, $expr:expr) => { + [$expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr] + }; + (9, $expr:expr) => { + [ + $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, + ] + }; + (10, $expr:expr) => { + [ + $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, + ] + }; + (11, $expr:expr) => { + [ + $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, + ] + }; + (12, $expr:expr) => { + [ + $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, + ] + }; + (13, $expr:expr) => { + [ + $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, + $expr, + ] + }; + (14, $expr:expr) => { + [ + $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, + $expr, $expr, + ] + }; + (15, $expr:expr) => { + [ + $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, + $expr, $expr, $expr, + ] + }; + (16, $expr:expr) => { + [ + $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, $expr, + $expr, $expr, $expr, $expr, + ] + }; } macro_rules! impl_for_array { ($count:tt) => { - impl< 'a, C, T > Readable< 'a, C > for [T; $count] where C: Context, T: Readable< 'a, C > { + impl<'a, C, T> Readable<'a, C> for [T; $count] + where + C: Context, + T: Readable<'a, C>, + { #[inline(always)] - fn read_from< R >( reader: &mut R ) -> Result< Self, C::Error > where R: Reader< 'a, C > { - let array = repeat!( $count, reader.read_value()? ); - Ok( array ) + fn read_from(reader: &mut R) -> Result + where + R: Reader<'a, C>, + { + let array = repeat!($count, reader.read_value()?); + Ok(array) } #[inline] @@ -545,33 +650,37 @@ macro_rules! impl_for_array { T::minimum_bytes_needed() * $count } } - } -} - -impl_for_array!( 1 ); -impl_for_array!( 2 ); -impl_for_array!( 3 ); -impl_for_array!( 4 ); -impl_for_array!( 5 ); -impl_for_array!( 6 ); -impl_for_array!( 7 ); -impl_for_array!( 8 ); -impl_for_array!( 9 ); -impl_for_array!( 10 ); -impl_for_array!( 11 ); -impl_for_array!( 12 ); -impl_for_array!( 13 ); -impl_for_array!( 14 ); -impl_for_array!( 15 ); -impl_for_array!( 16 ); - -impl< 'a, C, T > Readable< 'a, C > for Box< T > - where C: Context, - T: Readable< 'a, C > + }; +} + +impl_for_array!(1); +impl_for_array!(2); +impl_for_array!(3); +impl_for_array!(4); +impl_for_array!(5); +impl_for_array!(6); +impl_for_array!(7); +impl_for_array!(8); +impl_for_array!(9); +impl_for_array!(10); +impl_for_array!(11); +impl_for_array!(12); +impl_for_array!(13); +impl_for_array!(14); +impl_for_array!(15); +impl_for_array!(16); + +impl<'a, C, T> Readable<'a, C> for Box +where + C: Context, + T: Readable<'a, C>, { #[inline] - fn read_from< R >( reader: &mut R ) -> Result< Self, C::Error > where R: Reader< 'a, C > { - Ok( Box::new( T::read_from( reader )? ) ) + fn read_from(reader: &mut R) -> Result + where + R: Reader<'a, C>, + { + Ok(Box::new(T::read_from(reader)?)) } #[inline] @@ -580,33 +689,41 @@ impl< 'a, C, T > Readable< 'a, C > for Box< T > } } -impl< 'a, C, T > Readable< 'a, C > for Box< [T] > - where C: Context, - T: Readable< 'a, C > +impl<'a, C, T> Readable<'a, C> for Box<[T]> +where + C: Context, + T: Readable<'a, C>, { #[inline] - fn read_from< R >( reader: &mut R ) -> Result< Self, C::Error > where R: Reader< 'a, C > { - let data = Vec::< T >::read_from( reader )?; - Ok( data.into() ) + fn read_from(reader: &mut R) -> Result + where + R: Reader<'a, C>, + { + let data = Vec::::read_from(reader)?; + Ok(data.into()) } #[inline] fn minimum_bytes_needed() -> usize { - Vec::< T >::minimum_bytes_needed() + Vec::::minimum_bytes_needed() } } -impl< 'a, C > Readable< 'a, C > for Box< str > - where C: Context +impl<'a, C> Readable<'a, C> for Box +where + C: Context, { #[inline] - fn read_from< R >( reader: &mut R ) -> Result< Self, C::Error > where R: Reader< 'a, C > { - let data = String::read_from( reader )?; - Ok( data.into() ) + fn read_from(reader: &mut R) -> Result + where + R: Reader<'a, C>, + { + let data = String::read_from(reader)?; + Ok(data.into()) } #[inline] fn minimum_bytes_needed() -> usize { - >::minimum_bytes_needed() + >::minimum_bytes_needed() } } diff --git a/src/readable_unsized_impl.rs b/src/readable_unsized_impl.rs index 54d73f6..6b73b47 100644 --- a/src/readable_unsized_impl.rs +++ b/src/readable_unsized_impl.rs @@ -1,40 +1,41 @@ -use { - crate::{ - Readable, - Reader, - Context - } -}; +use crate::{Context, Readable, Reader}; -impl< 'a, C: Context > Readable< 'a, C > for &'a str { +impl<'a, C: Context> Readable<'a, C> for &'a str { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - let length = crate::private::read_length( reader )?; - let bytes = reader.read_bytes_borrowed( length ).ok_or_else( crate::error::error_unsized )??; - let value = std::str::from_utf8( bytes ).map_err( crate::error::error_invalid_str_utf8 )?; - Ok( value ) + fn read_from>(reader: &mut R) -> Result { + let length = crate::private::read_length(reader)?; + let bytes = reader + .read_bytes_borrowed(length) + .ok_or_else(crate::error::error_unsized)??; + let value = std::str::from_utf8(bytes).map_err(crate::error::error_invalid_str_utf8)?; + Ok(value) } #[inline] fn minimum_bytes_needed() -> usize { - >::minimum_bytes_needed() + >::minimum_bytes_needed() } } -impl< 'a, C: Context, T > Readable< 'a, C > for &'a [T] where T: crate::utils::ZeroCopyable< T > { +impl<'a, C: Context, T> Readable<'a, C> for &'a [T] +where + T: crate::utils::ZeroCopyable, +{ #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - if std::mem::size_of::< T >() != 1 && reader.endianness().conversion_necessary() { - return Err( crate::error::error_endianness_mismatch() ); + fn read_from>(reader: &mut R) -> Result { + if std::mem::size_of::() != 1 && reader.endianness().conversion_necessary() { + return Err(crate::error::error_endianness_mismatch()); } - let length = crate::private::read_length( reader )?; - let bytelength = length.checked_mul( std::mem::size_of::< T >() ).ok_or_else( crate::error::error_out_of_range_length )?; - let bytes = reader.read_bytes_borrowed( bytelength ).ok_or_else( crate::error::error_unsized )??; - let slice = unsafe { - std::slice::from_raw_parts( bytes.as_ptr() as *const T, length ) - }; - Ok( slice ) + let length = crate::private::read_length(reader)?; + let bytelength = length + .checked_mul(std::mem::size_of::()) + .ok_or_else(crate::error::error_out_of_range_length)?; + let bytes = reader + .read_bytes_borrowed(bytelength) + .ok_or_else(crate::error::error_unsized)??; + let slice = unsafe { std::slice::from_raw_parts(bytes.as_ptr() as *const T, length) }; + Ok(slice) } #[inline] @@ -44,26 +45,29 @@ impl< 'a, C: Context, T > Readable< 'a, C > for &'a [T] where T: crate::utils::Z } #[inline(always)] -unsafe fn cast_slice< T, const N: usize >( slice: &[u8] ) -> &[T; N] { - unsafe { - &*(slice.as_ptr() as *const [T; N]) - } +unsafe fn cast_slice(slice: &[u8]) -> &[T; N] { + unsafe { &*(slice.as_ptr() as *const [T; N]) } } -impl< 'a, C: Context, T, const N: usize > Readable< 'a, C > for &'a [T; N] where T: crate::utils::ZeroCopyable< T > { +impl<'a, C: Context, T, const N: usize> Readable<'a, C> for &'a [T; N] +where + T: crate::utils::ZeroCopyable, +{ #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - if std::mem::size_of::< T >() != 1 && reader.endianness().conversion_necessary() { - return Err( crate::error::error_endianness_mismatch() ); + fn read_from>(reader: &mut R) -> Result { + if std::mem::size_of::() != 1 && reader.endianness().conversion_necessary() { + return Err(crate::error::error_endianness_mismatch()); } - let bytes = reader.read_bytes_borrowed( std::mem::size_of::< T >() * N ).ok_or_else( crate::error::error_unsized )??; - let slice = unsafe { cast_slice( bytes ) }; - Ok( slice ) + let bytes = reader + .read_bytes_borrowed(std::mem::size_of::() * N) + .ok_or_else(crate::error::error_unsized)??; + let slice = unsafe { cast_slice(bytes) }; + Ok(slice) } #[inline] fn minimum_bytes_needed() -> usize { - std::mem::size_of::< T >() * N + std::mem::size_of::() * N } } diff --git a/src/reader.rs b/src/reader.rs index 18db8f9..9812ee6 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -1,82 +1,91 @@ -use std::mem::{self, MaybeUninit}; use std::borrow::Cow; use std::iter::FromIterator; +use std::mem::{self, MaybeUninit}; +use crate::context::Context; use crate::endianness::Endianness; use crate::readable::Readable; -use crate::context::Context; use crate::varint::VarInt64; use crate::error::error_end_of_input; use crate::error::IsEof; use crate::utils::SwapBytes; -struct RawCopyIter< T > { - pointer: std::ptr::NonNull< T >, - end: *const T +struct RawCopyIter { + pointer: std::ptr::NonNull, + end: *const T, } -impl< T > Iterator for RawCopyIter< T > { +impl Iterator for RawCopyIter { type Item = T; #[inline(always)] - fn next( &mut self ) -> Option< Self::Item > { + fn next(&mut self) -> Option { if self.pointer.as_ptr() as *const T == self.end { return None; } else { unsafe { let old = self.pointer.as_ptr(); - self.pointer = std::ptr::NonNull::new_unchecked( old.add( 1 ) ); - Some( std::ptr::read_unaligned( old ) ) + self.pointer = std::ptr::NonNull::new_unchecked(old.add(1)); + Some(std::ptr::read_unaligned(old)) } } } #[inline(always)] - fn size_hint( &self ) -> (usize, Option< usize >) { + fn size_hint(&self) -> (usize, Option) { let length = self.len(); - (length, Some( length )) + (length, Some(length)) } } -impl< T > ExactSizeIterator for RawCopyIter< T > { +impl ExactSizeIterator for RawCopyIter { #[inline(always)] fn len(&self) -> usize { let bytesize = self.end as usize - self.pointer.as_ptr() as usize; - bytesize / std::mem::size_of::< T >() + bytesize / std::mem::size_of::() } } -impl< T > std::iter::FusedIterator for RawCopyIter< T > {} +impl std::iter::FusedIterator for RawCopyIter {} -pub trait Reader< 'a, C: Context >: Sized { - fn read_bytes( &mut self, output: &mut [u8] ) -> Result< (), C::Error >; - fn peek_bytes( &mut self, output: &mut [u8] ) -> Result< (), C::Error >; - fn context( &self ) -> &C; - fn context_mut( &mut self ) -> &mut C; +pub trait Reader<'a, C: Context>: Sized { + fn read_bytes(&mut self, output: &mut [u8]) -> Result<(), C::Error>; + fn peek_bytes(&mut self, output: &mut [u8]) -> Result<(), C::Error>; + fn context(&self) -> &C; + fn context_mut(&mut self) -> &mut C; #[inline(always)] - unsafe fn read_bytes_into_ptr( &mut self, output: *mut u8, length: usize ) -> Result< (), C::Error > { - unsafe { - self.read_bytes( std::slice::from_raw_parts_mut( output, length ) ) - } + unsafe fn read_bytes_into_ptr( + &mut self, + output: *mut u8, + length: usize, + ) -> Result<(), C::Error> { + unsafe { self.read_bytes(std::slice::from_raw_parts_mut(output, length)) } } #[inline(always)] - unsafe fn peek_bytes_into_ptr( &mut self, output: *mut u8, length: usize ) -> Result< (), C::Error > { - unsafe { - self.peek_bytes( std::slice::from_raw_parts_mut( output, length ) ) - } + unsafe fn peek_bytes_into_ptr( + &mut self, + output: *mut u8, + length: usize, + ) -> Result<(), C::Error> { + unsafe { self.peek_bytes(std::slice::from_raw_parts_mut(output, length)) } } #[inline(always)] - fn skip_bytes( &mut self, mut length: usize ) -> Result< (), C::Error > { + fn skip_bytes(&mut self, mut length: usize) -> Result<(), C::Error> { const CHUNK_SIZE: usize = 1024; - let mut dummy_buffer: [MaybeUninit< u8 >; CHUNK_SIZE] = unsafe { MaybeUninit::uninit().assume_init() }; + let mut dummy_buffer: [MaybeUninit; CHUNK_SIZE] = + unsafe { MaybeUninit::uninit().assume_init() }; while length > 0 { - let chunk_size = if length < CHUNK_SIZE { length } else { CHUNK_SIZE }; - let dummy_buffer: *mut MaybeUninit< u8 > = dummy_buffer.as_mut_ptr(); + let chunk_size = if length < CHUNK_SIZE { + length + } else { + CHUNK_SIZE + }; + let dummy_buffer: *mut MaybeUninit = dummy_buffer.as_mut_ptr(); unsafe { - self.read_bytes_into_ptr( dummy_buffer as *mut u8, chunk_size )?; + self.read_bytes_into_ptr(dummy_buffer as *mut u8, chunk_size)?; } length -= chunk_size; } @@ -85,618 +94,657 @@ pub trait Reader< 'a, C: Context >: Sized { } #[inline(always)] - fn can_read_at_least( &self, _size: usize ) -> Option< bool > { + fn can_read_at_least(&self, _size: usize) -> Option { None } #[inline(always)] - fn read_bytes_borrowed( &mut self, _length: usize ) -> Option< Result< &'a [u8], C::Error > > { + fn read_bytes_borrowed(&mut self, _length: usize) -> Option> { None } #[inline(always)] - fn read_bytes_borrowed_from_reader< 'r >( &'r mut self, _length: usize ) -> Option< Result< &'r [u8], C::Error > > { + fn read_bytes_borrowed_from_reader<'r>( + &'r mut self, + _length: usize, + ) -> Option> { None } #[inline(always)] - fn read_bytes_borrowed_until_eof( &mut self ) -> Option< &'a [u8] > { + fn read_bytes_borrowed_until_eof(&mut self) -> Option<&'a [u8]> { None } #[inline(always)] - fn read_u8( &mut self ) -> Result< u8, C::Error > { - if self.can_read_at_least( 1 ) == Some( false ) { - return Err( error_end_of_input() ); + fn read_u8(&mut self) -> Result { + if self.can_read_at_least(1) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< u8 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.read_bytes_into_ptr( value.as_mut_ptr(), 1 )?; - Ok( value.assume_init() ) + self.read_bytes_into_ptr(value.as_mut_ptr(), 1)?; + Ok(value.assume_init()) } } #[inline(always)] - fn peek_u8( &mut self ) -> Result< u8, C::Error > { - if self.can_read_at_least( 1 ) == Some( false ) { - return Err( error_end_of_input() ); + fn peek_u8(&mut self) -> Result { + if self.can_read_at_least(1) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< u8 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.peek_bytes_into_ptr( value.as_mut_ptr(), 1 )?; - Ok( value.assume_init() ) + self.peek_bytes_into_ptr(value.as_mut_ptr(), 1)?; + Ok(value.assume_init()) } } #[inline(always)] - fn read_i8( &mut self ) -> Result< i8, C::Error > { - self.read_u8().map( |byte| byte as i8 ) + fn read_i8(&mut self) -> Result { + self.read_u8().map(|byte| byte as i8) } #[inline(always)] - fn peek_i8( &mut self ) -> Result< i8, C::Error > { - self.peek_u8().map( |byte| byte as i8 ) + fn peek_i8(&mut self) -> Result { + self.peek_u8().map(|byte| byte as i8) } #[inline(always)] - fn read_u16( &mut self ) -> Result< u16, C::Error > { - if self.can_read_at_least( 2 ) == Some( false ) { - return Err( error_end_of_input() ); + fn read_u16(&mut self) -> Result { + if self.can_read_at_least(2) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< u16 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.read_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 2 )?; + self.read_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 2)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn peek_u16( &mut self ) -> Result< u16, C::Error > { - if self.can_read_at_least( 2 ) == Some( false ) { - return Err( error_end_of_input() ); + fn peek_u16(&mut self) -> Result { + if self.can_read_at_least(2) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< u16 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.peek_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 2 )?; + self.peek_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 2)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn read_i16( &mut self ) -> Result< i16, C::Error > { - if self.can_read_at_least( 2 ) == Some( false ) { - return Err( error_end_of_input() ); + fn read_i16(&mut self) -> Result { + if self.can_read_at_least(2) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< i16 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.read_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 2 )?; + self.read_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 2)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn peek_i16( &mut self ) -> Result< i16, C::Error > { - if self.can_read_at_least( 2 ) == Some( false ) { - return Err( error_end_of_input() ); + fn peek_i16(&mut self) -> Result { + if self.can_read_at_least(2) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< i16 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.peek_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 2 )?; + self.peek_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 2)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn read_u32( &mut self ) -> Result< u32, C::Error > { - if self.can_read_at_least( 4 ) == Some( false ) { - return Err( error_end_of_input() ); + fn read_u32(&mut self) -> Result { + if self.can_read_at_least(4) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< u32 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.read_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 4 )?; + self.read_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 4)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn peek_u32( &mut self ) -> Result< u32, C::Error > { - if self.can_read_at_least( 4 ) == Some( false ) { - return Err( error_end_of_input() ); + fn peek_u32(&mut self) -> Result { + if self.can_read_at_least(4) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< u32 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.peek_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 4 )?; + self.peek_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 4)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn read_i32( &mut self ) -> Result< i32, C::Error > { - if self.can_read_at_least( 4 ) == Some( false ) { - return Err( error_end_of_input() ); + fn read_i32(&mut self) -> Result { + if self.can_read_at_least(4) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< i32 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.read_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 4 )?; + self.read_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 4)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn peek_i32( &mut self ) -> Result< i32, C::Error > { - if self.can_read_at_least( 4 ) == Some( false ) { - return Err( error_end_of_input() ); + fn peek_i32(&mut self) -> Result { + if self.can_read_at_least(4) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< i32 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.peek_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 4 )?; + self.peek_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 4)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn read_u64( &mut self ) -> Result< u64, C::Error > { - if self.can_read_at_least( 8 ) == Some( false ) { - return Err( error_end_of_input() ); + fn read_u64(&mut self) -> Result { + if self.can_read_at_least(8) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< u64 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.read_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 8 )?; + self.read_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 8)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn peek_u64( &mut self ) -> Result< u64, C::Error > { - if self.can_read_at_least( 8 ) == Some( false ) { - return Err( error_end_of_input() ); + fn peek_u64(&mut self) -> Result { + if self.can_read_at_least(8) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< u64 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.peek_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 8 )?; + self.peek_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 8)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn read_i64( &mut self ) -> Result< i64, C::Error > { - if self.can_read_at_least( 8 ) == Some( false ) { - return Err( error_end_of_input() ); + fn read_i64(&mut self) -> Result { + if self.can_read_at_least(8) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< i64 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.read_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 8 )?; + self.read_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 8)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn peek_i64( &mut self ) -> Result< i64, C::Error > { - if self.can_read_at_least( 8 ) == Some( false ) { - return Err( error_end_of_input() ); + fn peek_i64(&mut self) -> Result { + if self.can_read_at_least(8) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< i64 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.peek_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 8 )?; + self.peek_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 8)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn read_u128( &mut self ) -> Result< u128, C::Error > { - if self.can_read_at_least( 16 ) == Some( false ) { - return Err( error_end_of_input() ); + fn read_u128(&mut self) -> Result { + if self.can_read_at_least(16) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< u128 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.read_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 16 )?; + self.read_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 16)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn peek_u128( &mut self ) -> Result< u128, C::Error > { - if self.can_read_at_least( 16 ) == Some( false ) { - return Err( error_end_of_input() ); + fn peek_u128(&mut self) -> Result { + if self.can_read_at_least(16) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< u128 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.peek_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 16 )?; + self.peek_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 16)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn read_i128( &mut self ) -> Result< i128, C::Error > { - if self.can_read_at_least( 16 ) == Some( false ) { - return Err( error_end_of_input() ); + fn read_i128(&mut self) -> Result { + if self.can_read_at_least(16) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< i128 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.read_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 16 )?; + self.read_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 16)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn peek_i128( &mut self ) -> Result< i128, C::Error > { - if self.can_read_at_least( 16 ) == Some( false ) { - return Err( error_end_of_input() ); + fn peek_i128(&mut self) -> Result { + if self.can_read_at_least(16) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< i128 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.peek_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 16 )?; + self.peek_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 16)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn read_f32( &mut self ) -> Result< f32, C::Error > { - if self.can_read_at_least( 4 ) == Some( false ) { - return Err( error_end_of_input() ); + fn read_f32(&mut self) -> Result { + if self.can_read_at_least(4) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< f32 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.read_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 4 )?; + self.read_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 4)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn peek_f32( &mut self ) -> Result< f32, C::Error > { - if self.can_read_at_least( 4 ) == Some( false ) { - return Err( error_end_of_input() ); + fn peek_f32(&mut self) -> Result { + if self.can_read_at_least(4) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< f32 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.peek_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 4 )?; + self.peek_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 4)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn read_f64( &mut self ) -> Result< f64, C::Error > { - if self.can_read_at_least( 8 ) == Some( false ) { - return Err( error_end_of_input() ); + fn read_f64(&mut self) -> Result { + if self.can_read_at_least(8) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< f64 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.read_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 8 )?; + self.read_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 8)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn peek_f64( &mut self ) -> Result< f64, C::Error > { - if self.can_read_at_least( 8 ) == Some( false ) { - return Err( error_end_of_input() ); + fn peek_f64(&mut self) -> Result { + if self.can_read_at_least(8) == Some(false) { + return Err(error_end_of_input()); } - let mut value: MaybeUninit< f64 > = MaybeUninit::uninit(); + let mut value: MaybeUninit = MaybeUninit::uninit(); unsafe { - self.peek_bytes_into_ptr( value.as_mut_ptr() as *mut u8, 8 )?; + self.peek_bytes_into_ptr(value.as_mut_ptr() as *mut u8, 8)?; let value = value.assume_init(); if self.context().endianness().conversion_necessary() { - Ok( value.swap_bytes() ) + Ok(value.swap_bytes()) } else { - Ok( value ) + Ok(value) } } } #[inline(always)] - fn read_value< T: Readable< 'a, C > >( &mut self ) -> Result< T, C::Error > { - T::read_from( self ) + fn read_value>(&mut self) -> Result { + T::read_from(self) } #[inline(always)] - fn endianness( &self ) -> Endianness { + fn endianness(&self) -> Endianness { self.context().endianness() } #[inline] - fn read_vec< T >( &mut self, length: usize ) -> Result< Vec< T >, C::Error > - where T: Readable< 'a, C > + fn read_vec(&mut self, length: usize) -> Result, C::Error> + where + T: Readable<'a, C>, { - let (required, overflow) = T::minimum_bytes_needed().overflowing_mul( length ); - if overflow || self.can_read_at_least( required ) == Some( false ) { - return Err( error_end_of_input() ); + let (required, overflow) = T::minimum_bytes_needed().overflowing_mul(length); + if overflow || self.can_read_at_least(required) == Some(false) { + return Err(error_end_of_input()); } - let mut vec = Vec::with_capacity( length ); + let mut vec = Vec::with_capacity(length); if T::speedy_is_primitive() { unsafe { - self.read_bytes_into_ptr( vec.as_mut_ptr() as *mut u8, vec.capacity() * std::mem::size_of::< T >() )?; - vec.set_len( length ); + self.read_bytes_into_ptr( + vec.as_mut_ptr() as *mut u8, + vec.capacity() * std::mem::size_of::(), + )?; + vec.set_len(length); } - T::speedy_convert_slice_endianness( self.endianness(), &mut vec ); + T::speedy_convert_slice_endianness(self.endianness(), &mut vec); } else { #[inline(never)] #[cold] - fn drop_vec< T >( mut vec: Vec< T >, length: usize ) { + fn drop_vec(mut vec: Vec, length: usize) { unsafe { - vec.set_len( length ); + vec.set_len(length); } - std::mem::drop( vec ); + std::mem::drop(vec); } let mut p = vec.as_mut_ptr(); - let e = unsafe { p.add( length ) }; + let e = unsafe { p.add(length) }; // We deliberately have a separate counter instead // of substracting pointers as this optimizes better. let mut count = 0; while p < e { let value = match self.read_value() { - Ok( value ) => value, - Err( error ) => { - drop_vec( vec, count ); - return Err( error ); + Ok(value) => value, + Err(error) => { + drop_vec(vec, count); + return Err(error); } }; unsafe { - std::ptr::write( p, value ); - p = p.add( 1 ); + std::ptr::write(p, value); + p = p.add(1); count += 1; } } unsafe { - vec.set_len( length ); + vec.set_len(length); } } - Ok( vec ) + Ok(vec) } #[inline] - fn read_vec_until_eof< T >( &mut self ) -> Result< Vec< T >, C::Error > - where T: Readable< 'a, C > + fn read_vec_until_eof(&mut self) -> Result, C::Error> + where + T: Readable<'a, C>, { // TODO: Optimize this. - let mut vec: Vec< T > = Vec::new(); + let mut vec: Vec = Vec::new(); loop { let value = match self.read_value() { - Ok( value ) => value, - Err( error ) if error.is_eof() => break, - Err( error ) => return Err( error ) + Ok(value) => value, + Err(error) if error.is_eof() => break, + Err(error) => return Err(error), }; - vec.push( value ); + vec.push(value); } - Ok( vec ) + Ok(vec) } #[inline] - fn read_cow< T >( &mut self, length: usize ) -> Result< Cow< 'a, [T] >, C::Error > - where T: Readable< 'a, C >, - [T]: ToOwned< Owned = Vec< T > > + fn read_cow(&mut self, length: usize) -> Result, C::Error> + where + T: Readable<'a, C>, + [T]: ToOwned>, { - if T::speedy_is_primitive() && (mem::size_of::< T >() == 1 || !self.endianness().conversion_necessary()) { - if let Some( bytes ) = self.read_bytes_borrowed( length * mem::size_of::< T >() ) { + if T::speedy_is_primitive() + && (mem::size_of::() == 1 || !self.endianness().conversion_necessary()) + { + if let Some(bytes) = self.read_bytes_borrowed(length * mem::size_of::()) { let bytes = bytes?; - assert_eq!( bytes.len(), length * mem::size_of::< T >() ); + assert_eq!(bytes.len(), length * mem::size_of::()); - if mem::align_of::< T >() == 1 || bytes.as_ptr() as usize % mem::align_of::< T >() == 0 { - let slice = unsafe { T::speedy_slice_from_bytes( bytes ) }; - return Ok( Cow::Borrowed( slice ) ); + if mem::align_of::() == 1 || bytes.as_ptr() as usize % mem::align_of::() == 0 + { + let slice = unsafe { T::speedy_slice_from_bytes(bytes) }; + return Ok(Cow::Borrowed(slice)); } else { - let mut vec: Vec< T > = Vec::with_capacity( length ); + let mut vec: Vec = Vec::with_capacity(length); unsafe { - std::ptr::copy_nonoverlapping( bytes.as_ptr(), vec.as_mut_ptr() as *mut u8, bytes.len() ); - vec.set_len( length ); + std::ptr::copy_nonoverlapping( + bytes.as_ptr(), + vec.as_mut_ptr() as *mut u8, + bytes.len(), + ); + vec.set_len(length); } - return Ok( Cow::Owned( vec ) ); + return Ok(Cow::Owned(vec)); } } } - Ok( Cow::Owned( self.read_vec( length )? ) ) + Ok(Cow::Owned(self.read_vec(length)?)) } #[inline] - fn read_cow_until_eof< T >( &mut self ) -> Result< Cow< 'a, [T] >, C::Error > - where T: Readable< 'a, C >, - [T]: ToOwned< Owned = Vec< T > > + fn read_cow_until_eof(&mut self) -> Result, C::Error> + where + T: Readable<'a, C>, + [T]: ToOwned>, { // TODO: Optimize this. - Ok( Cow::Owned( self.read_vec_until_eof()? ) ) + Ok(Cow::Owned(self.read_vec_until_eof()?)) } #[inline] - fn read_string( &mut self, length: usize ) -> Result< String, C::Error > { - let bytes = self.read_vec( length )?; - crate::private::vec_to_string( bytes ) + fn read_string(&mut self, length: usize) -> Result { + let bytes = self.read_vec(length)?; + crate::private::vec_to_string(bytes) } #[inline] - fn read_collection< T, U >( &mut self, length: usize ) -> Result< U, C::Error > - where U: FromIterator< T >, - T: Readable< 'a, C > + fn read_collection(&mut self, length: usize) -> Result + where + U: FromIterator, + T: Readable<'a, C>, { - if T::speedy_is_primitive() && (mem::size_of::< T >() == 1 || !self.endianness().conversion_necessary()) { - let bytesize = length.checked_mul( std::mem::size_of::< T >() ).ok_or_else( || { - crate::error::error_too_big_usize_for_this_architecture() // TODO: Use different error maybe? - })?; - - if let Some( bytes ) = self.read_bytes_borrowed_from_reader( bytesize ) { + if T::speedy_is_primitive() + && (mem::size_of::() == 1 || !self.endianness().conversion_necessary()) + { + let bytesize = length + .checked_mul(std::mem::size_of::()) + .ok_or_else(|| { + crate::error::error_too_big_usize_for_this_architecture() // TODO: Use different error maybe? + })?; + + if let Some(bytes) = self.read_bytes_borrowed_from_reader(bytesize) { let bytes = bytes?; unsafe { - let pointer = bytes.as_ptr().cast::< T >(); - return Ok( RawCopyIter { pointer: std::ptr::NonNull::new_unchecked( pointer as *mut T ), end: pointer.add( length ) }.collect() ); + let pointer = bytes.as_ptr().cast::(); + return Ok(RawCopyIter { + pointer: std::ptr::NonNull::new_unchecked(pointer as *mut T), + end: pointer.add(length), + } + .collect()); } } } - (0..length).into_iter().map( |_| self.read_value::< T >() ).collect() + (0..length) + .into_iter() + .map(|_| self.read_value::()) + .collect() } #[inline] - fn read_key_value_collection< K, V, U >( &mut self, length: usize ) -> Result< U, C::Error > - where U: FromIterator< (K, V) >, - K: Readable< 'a, C >, - V: Readable< 'a, C > + fn read_key_value_collection(&mut self, length: usize) -> Result + where + U: FromIterator<(K, V)>, + K: Readable<'a, C>, + V: Readable<'a, C>, { #[repr(packed)] - struct Pair< K, V >( K, V ); - - if K::speedy_is_primitive() && V::speedy_is_primitive() && ((mem::size_of::< K >() == 1 && mem::size_of::< V >() == 1) || !self.endianness().conversion_necessary()) { - let bytesize = length.checked_mul( std::mem::size_of::< Pair< K, V > >() ).ok_or_else( || { - crate::error::error_too_big_usize_for_this_architecture() - })?; - - if let Some( bytes ) = self.read_bytes_borrowed_from_reader( bytesize ) { + struct Pair(K, V); + + if K::speedy_is_primitive() + && V::speedy_is_primitive() + && ((mem::size_of::() == 1 && mem::size_of::() == 1) + || !self.endianness().conversion_necessary()) + { + let bytesize = length + .checked_mul(std::mem::size_of::>()) + .ok_or_else(|| crate::error::error_too_big_usize_for_this_architecture())?; + + if let Some(bytes) = self.read_bytes_borrowed_from_reader(bytesize) { let bytes = bytes?; unsafe { - let pointer = bytes.as_ptr().cast::< Pair< K, V > >(); - return Ok( RawCopyIter { pointer: std::ptr::NonNull::new_unchecked( pointer as *mut Pair< K, V > ), end: pointer.add( length ) }.map( |pair| (pair.0, pair.1) ).collect() ); + let pointer = bytes.as_ptr().cast::>(); + return Ok(RawCopyIter { + pointer: std::ptr::NonNull::new_unchecked(pointer as *mut Pair), + end: pointer.add(length), + } + .map(|pair| (pair.0, pair.1)) + .collect()); } } } - self.read_collection( length ) + self.read_collection(length) } #[inline] - fn read_collection_until_eof< T, U >( &mut self ) -> Result< U, C::Error > - where U: FromIterator< T >, - T: Readable< 'a, C > + fn read_collection_until_eof(&mut self) -> Result + where + U: FromIterator, + T: Readable<'a, C>, { - std::iter::from_fn( move || { - match self.read_value::< T >() { - Ok( value ) => Some( Ok( value ) ), - Err( error ) if error.is_eof() => None, - Err( error ) => Some( Err( error ) ) - } - }).collect() + std::iter::from_fn(move || match self.read_value::() { + Ok(value) => Some(Ok(value)), + Err(error) if error.is_eof() => None, + Err(error) => Some(Err(error)), + }) + .collect() } #[inline] - fn read_u64_varint( &mut self ) -> Result< u64, C::Error > { - let value = VarInt64::read_from( self )?; - Ok( value.into() ) + fn read_u64_varint(&mut self) -> Result { + let value = VarInt64::read_from(self)?; + Ok(value.into()) } #[inline] - fn peek_u64_varint( &mut self ) -> Result< u64, C::Error > { - let value = VarInt64::peek_from( self )?; - Ok( value.into() ) + fn peek_u64_varint(&mut self) -> Result { + let value = VarInt64::peek_from(self)?; + Ok(value.into()) } } diff --git a/src/utils.rs b/src/utils.rs index cc2f178..23090f7 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -14,24 +14,28 @@ macro_rules! unsafe_is_length { // in certain cases. unsafe { std::hint::unreachable_unchecked() } } - } + }; } // TODO: Remove the T parameter once #![feature(trivial_bounds)] is stable. -pub unsafe trait ZeroCopyable< T > where T: ?Sized {} -unsafe impl< T > ZeroCopyable< T > for i8 {} -unsafe impl< T > ZeroCopyable< T > for u8 {} +pub unsafe trait ZeroCopyable +where + T: ?Sized, +{ +} +unsafe impl ZeroCopyable for i8 {} +unsafe impl ZeroCopyable for u8 {} pub trait SwapBytes { - fn swap_bytes( self ) -> Self; + fn swap_bytes(self) -> Self; } impl SwapBytes for f32 { #[inline(always)] - fn swap_bytes( self ) -> Self { + fn swap_bytes(self) -> Self { union Union { float: f32, - int: u32 + int: u32, } unsafe { @@ -44,10 +48,10 @@ impl SwapBytes for f32 { impl SwapBytes for f64 { #[inline(always)] - fn swap_bytes( self ) -> Self { + fn swap_bytes(self) -> Self { union Union { float: f64, - int: u64 + int: u64, } unsafe { diff --git a/src/varint.rs b/src/varint.rs index 917d153..dd1e781 100644 --- a/src/varint.rs +++ b/src/varint.rs @@ -1,12 +1,4 @@ -use { - crate::{ - Context, - Readable, - Reader, - Writable, - Writer - } -}; +use crate::{Context, Readable, Reader, Writable, Writer}; // Encoding: // At most 7bit - 0xxxxxxx @@ -26,78 +18,78 @@ use { #[repr(transparent)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] -pub struct VarInt64( u64 ); +pub struct VarInt64(u64); -impl From< u64 > for VarInt64 { +impl From for VarInt64 { #[inline] - fn from( value: u64 ) -> Self { - VarInt64( value ) + fn from(value: u64) -> Self { + VarInt64(value) } } -impl From< u32 > for VarInt64 { +impl From for VarInt64 { #[inline] - fn from( value: u32 ) -> Self { - VarInt64( value as u64 ) + fn from(value: u32) -> Self { + VarInt64(value as u64) } } -impl From< u16 > for VarInt64 { +impl From for VarInt64 { #[inline] - fn from( value: u16 ) -> Self { - VarInt64( value as u64 ) + fn from(value: u16) -> Self { + VarInt64(value as u64) } } -impl From< u8 > for VarInt64 { +impl From for VarInt64 { #[inline] - fn from( value: u8 ) -> Self { - VarInt64( value as u64 ) + fn from(value: u8) -> Self { + VarInt64(value as u64) } } -impl From< i64 > for VarInt64 { +impl From for VarInt64 { #[inline] - fn from( value: i64 ) -> Self { + fn from(value: i64) -> Self { let value = (value << 1) ^ (value >> 63); - VarInt64( value as u64 ) + VarInt64(value as u64) } } -impl From< i32 > for VarInt64 { +impl From for VarInt64 { #[inline] - fn from( value: i32 ) -> Self { + fn from(value: i32) -> Self { let value = (value << 1) ^ (value >> 31); - VarInt64( value as u32 as u64 ) + VarInt64(value as u32 as u64) } } -impl From< i16 > for VarInt64 { +impl From for VarInt64 { #[inline] - fn from( value: i16 ) -> Self { + fn from(value: i16) -> Self { let value = (value << 1) ^ (value >> 15); - VarInt64( value as u16 as u64 ) + VarInt64(value as u16 as u64) } } -impl From< i8 > for VarInt64 { +impl From for VarInt64 { #[inline] - fn from( value: i8 ) -> Self { + fn from(value: i8) -> Self { let value = (value << 1) ^ (value >> 7); - VarInt64( value as u8 as u64 ) + VarInt64(value as u8 as u64) } } -impl From< VarInt64 > for u64 { +impl From for u64 { #[inline] - fn from( value: VarInt64 ) -> Self { + fn from(value: VarInt64) -> Self { value.0 } } -impl From< VarInt64 > for i64 { +impl From for i64 { #[inline] - fn from( value: VarInt64 ) -> Self { + fn from(value: VarInt64) -> Self { let value = value.0; ((value >> 1) ^ (value << 15)) as i64 } @@ -109,18 +101,20 @@ macro_rules! impl_read { let length = (!first_byte).leading_zeros(); let upper_mask = 0b11111111_u64 >> length; - let upper_bits = (upper_mask & (first_byte as u64)).wrapping_shl( length * 8 ); + let upper_bits = (upper_mask & (first_byte as u64)).wrapping_shl(length * 8); macro_rules! read { ($count:expr) => {{ let mut value: u64 = 0; { - let slice = unsafe { std::slice::from_raw_parts_mut( &mut value as *mut u64 as *mut u8, $count ) }; - $reader.$read_bytes( slice )?; + let slice = unsafe { + std::slice::from_raw_parts_mut(&mut value as *mut u64 as *mut u8, $count) + }; + $reader.$read_bytes(slice)?; } value = value.to_le(); - Ok( VarInt64( upper_bits | value ) ) - }} + Ok(VarInt64(upper_bits | value)) + }}; } match length { @@ -134,7 +128,7 @@ macro_rules! impl_read { 7 => read! { 7 }, 8 => read! { 8 }, _ => { - if cfg!( debug_assertions ) { + if cfg!(debug_assertions) { unreachable!() } else { unsafe { @@ -143,13 +137,13 @@ macro_rules! impl_read { } } } - }} + }}; } -impl< 'a, C: Context > Readable< 'a, C > for VarInt64 { +impl<'a, C: Context> Readable<'a, C> for VarInt64 { #[inline] - fn read_from< R: Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - impl_read!( reader, read_u8, read_bytes ) + fn read_from>(reader: &mut R) -> Result { + impl_read!(reader, read_u8, read_bytes) } #[inline] @@ -160,16 +154,17 @@ impl< 'a, C: Context > Readable< 'a, C > for VarInt64 { impl VarInt64 { #[inline] - pub(crate) fn peek_from< 'a, C, R >( reader: &mut R ) -> Result< Self, C::Error > - where C: Context, - R: Reader< 'a, C > + pub(crate) fn peek_from<'a, C, R>(reader: &mut R) -> Result + where + C: Context, + R: Reader<'a, C>, { - impl_read!( reader, peek_u8, peek_bytes ) + impl_read!(reader, peek_u8, peek_bytes) } } #[cfg(test)] -fn get_length_slow( leading_zeros: u32 ) -> u32 { +fn get_length_slow(leading_zeros: u32) -> u32 { let bits_required = 64 - leading_zeros; match bits_required { 0..=7 => 0, @@ -181,12 +176,12 @@ fn get_length_slow( leading_zeros: u32 ) -> u32 { 43..=49 => 6, 50..=56 => 7, 57..=64 => 8, - _ => unreachable!() + _ => unreachable!(), } } #[inline] -fn get_length( leading_zeros: u32 ) -> u32 { +fn get_length(leading_zeros: u32) -> u32 { let bits_required = 64 - leading_zeros; let x = bits_required >> 3; ((x + bits_required) ^ x) >> 3 @@ -195,75 +190,80 @@ fn get_length( leading_zeros: u32 ) -> u32 { #[test] fn test_get_length() { for zeros in 0..=64 { - assert_eq!( - get_length( zeros ), - get_length_slow( zeros ) - ); + assert_eq!(get_length(zeros), get_length_slow(zeros)); } } -impl< C: Context > Writable< C > for VarInt64 { +impl Writable for VarInt64 { #[inline] - fn write_to< T: ?Sized + Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error > { + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error> { let mut value = self.0; - let length = get_length( value.leading_zeros() ); + let length = get_length(value.leading_zeros()); - if let Some( false ) = writer.can_write_at_least( length as usize + 1 ) { - return Err( crate::error::error_end_of_output_buffer() ); + if let Some(false) = writer.can_write_at_least(length as usize + 1) { + return Err(crate::error::error_end_of_output_buffer()); } match length { - 0 => writer.write_u8( value as u8 ), + 0 => writer.write_u8(value as u8), 1 => { - writer.write_u8( 0b10000000 | (value >> 8) as u8 )?; + writer.write_u8(0b10000000 | (value >> 8) as u8)?; value = value.to_le(); - let slice = unsafe { std::slice::from_raw_parts( &value as *const u64 as *const u8, 1 ) }; - writer.write_bytes( slice ) - }, + let slice = + unsafe { std::slice::from_raw_parts(&value as *const u64 as *const u8, 1) }; + writer.write_bytes(slice) + } 2 => { - writer.write_u8( 0b11000000 | (value >> 16) as u8 )?; + writer.write_u8(0b11000000 | (value >> 16) as u8)?; value = value.to_le(); - let slice = unsafe { std::slice::from_raw_parts( &value as *const u64 as *const u8, 2 ) }; - writer.write_bytes( slice ) - }, + let slice = + unsafe { std::slice::from_raw_parts(&value as *const u64 as *const u8, 2) }; + writer.write_bytes(slice) + } 3 => { - writer.write_u8( 0b11100000 | (value >> 24) as u8 )?; + writer.write_u8(0b11100000 | (value >> 24) as u8)?; value = value.to_le(); - let slice = unsafe { std::slice::from_raw_parts( &value as *const u64 as *const u8, 3 ) }; - writer.write_bytes( slice ) - }, + let slice = + unsafe { std::slice::from_raw_parts(&value as *const u64 as *const u8, 3) }; + writer.write_bytes(slice) + } 4 => { - writer.write_u8( 0b11110000 | (value >> 32) as u8 )?; + writer.write_u8(0b11110000 | (value >> 32) as u8)?; value = value.to_le(); - let slice = unsafe { std::slice::from_raw_parts( &value as *const u64 as *const u8, 4 ) }; - writer.write_bytes( slice ) - }, + let slice = + unsafe { std::slice::from_raw_parts(&value as *const u64 as *const u8, 4) }; + writer.write_bytes(slice) + } 5 => { - writer.write_u8( 0b11111000 | (value >> 40) as u8 )?; + writer.write_u8(0b11111000 | (value >> 40) as u8)?; value = value.to_le(); - let slice = unsafe { std::slice::from_raw_parts( &value as *const u64 as *const u8, 5 ) }; - writer.write_bytes( slice ) - }, + let slice = + unsafe { std::slice::from_raw_parts(&value as *const u64 as *const u8, 5) }; + writer.write_bytes(slice) + } 6 => { - writer.write_u8( 0b11111100 | (value >> 48) as u8 )?; + writer.write_u8(0b11111100 | (value >> 48) as u8)?; value = value.to_le(); - let slice = unsafe { std::slice::from_raw_parts( &value as *const u64 as *const u8, 6 ) }; - writer.write_bytes( slice ) - }, + let slice = + unsafe { std::slice::from_raw_parts(&value as *const u64 as *const u8, 6) }; + writer.write_bytes(slice) + } 7 => { - writer.write_u8( 0b11111110 | (value >> 56) as u8 )?; + writer.write_u8(0b11111110 | (value >> 56) as u8)?; value = value.to_le(); - let slice = unsafe { std::slice::from_raw_parts( &value as *const u64 as *const u8, 7 ) }; - writer.write_bytes( slice ) - }, + let slice = + unsafe { std::slice::from_raw_parts(&value as *const u64 as *const u8, 7) }; + writer.write_bytes(slice) + } 8 => { - writer.write_u8( 0b11111111 )?; + writer.write_u8(0b11111111)?; value = value.to_le(); - let slice = unsafe { std::slice::from_raw_parts( &value as *const u64 as *const u8, 8 ) }; - writer.write_bytes( slice ) - }, + let slice = + unsafe { std::slice::from_raw_parts(&value as *const u64 as *const u8, 8) }; + writer.write_bytes(slice) + } _ => { - if cfg!( debug_assertions ) { + if cfg!(debug_assertions) { unreachable!() } else { unsafe { @@ -275,8 +275,8 @@ impl< C: Context > Writable< C > for VarInt64 { } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Ok( get_length( self.0.leading_zeros() ) as usize + 1 ) + fn bytes_needed(&self) -> Result { + Ok(get_length(self.0.leading_zeros()) as usize + 1) } } @@ -325,16 +325,17 @@ fn test_varint64_serialization() { #[test] fn test_varint64_bruteforce() { - const fn hash32( x: u32 ) -> u32 { - let mut x = x.wrapping_mul( 0xa4d94a4f ); + const fn hash32(x: u32) -> u32 { + let mut x = x.wrapping_mul(0xa4d94a4f); let a = x >> 16; let b = x >> 30; x ^= a >> b; - x.wrapping_mul( 0xa4d94a4f ) + x.wrapping_mul(0xa4d94a4f) } - const fn hash64( x: u64 ) -> u64 { - (hash32( x as u32 ) as u64) | ((hash32( (x.wrapping_mul( 0xaaaaaaaa ) ^ 0xaaaaaaaa) as u32 ) as u64) << 32) + const fn hash64(x: u64) -> u64 { + (hash32(x as u32) as u64) + | ((hash32((x.wrapping_mul(0xaaaaaaaa) ^ 0xaaaaaaaa) as u32) as u64) << 32) } for n in 0..64 { @@ -342,24 +343,32 @@ fn test_varint64_bruteforce() { 1 << n, (1 << n) - 1, ((1 << n) - 1) << 1, - (1_u64 << n).wrapping_mul( 0b00000010 ), - (1_u64 << n).wrapping_mul( 0b00000101 ), - (1_u64 << n).wrapping_mul( 0b00001010 ), - (1_u64 << n).wrapping_mul( 0b00010101 ), - (1_u64 << n).wrapping_mul( 0b00101010 ), - (1_u64 << n).wrapping_mul( 0b01010101 ), - (1_u64 << n).wrapping_mul( 0b10101010 ), - hash64( n ) + (1_u64 << n).wrapping_mul(0b00000010), + (1_u64 << n).wrapping_mul(0b00000101), + (1_u64 << n).wrapping_mul(0b00001010), + (1_u64 << n).wrapping_mul(0b00010101), + (1_u64 << n).wrapping_mul(0b00101010), + (1_u64 << n).wrapping_mul(0b01010101), + (1_u64 << n).wrapping_mul(0b10101010), + hash64(n), ]; for &value in &values { - let value = VarInt64( value ); - let serialized_le = value.write_to_vec_with_ctx( crate::Endianness::LittleEndian ).unwrap(); - let deserialized = VarInt64::read_from_buffer_with_ctx( crate::Endianness::LittleEndian, &serialized_le ).unwrap(); - assert_eq!( deserialized, value ); - - let serialized_be = value.write_to_vec_with_ctx( crate::Endianness::BigEndian ).unwrap(); - assert_eq!( serialized_be, serialized_le ); + let value = VarInt64(value); + let serialized_le = value + .write_to_vec_with_ctx(crate::Endianness::LittleEndian) + .unwrap(); + let deserialized = VarInt64::read_from_buffer_with_ctx( + crate::Endianness::LittleEndian, + &serialized_le, + ) + .unwrap(); + assert_eq!(deserialized, value); + + let serialized_be = value + .write_to_vec_with_ctx(crate::Endianness::BigEndian) + .unwrap(); + assert_eq!(serialized_be, serialized_le); } } } diff --git a/src/writable.rs b/src/writable.rs index a916934..b94bdb9 100644 --- a/src/writable.rs +++ b/src/writable.rs @@ -1,234 +1,255 @@ -use std::io::{ - self, - Write -}; +use std::io::{self, Write}; use std::fs::File; use std::path::Path; -use crate::writer::Writer; use crate::context::{Context, DefaultContext}; use crate::endianness::Endianness; +use crate::writer::Writer; use crate::Error; -use crate::error::{ - error_end_of_output_buffer, - error_output_buffer_is_too_small -}; +use crate::error::{error_end_of_output_buffer, error_output_buffer_is_too_small}; -struct BufferCollector< 'a, C: Context > { +struct BufferCollector<'a, C: Context> { context: &'a mut C, buffer: &'a mut [u8], - position: usize + position: usize, } -impl< 'a, C: Context > Writer< C > for BufferCollector< 'a, C > { +impl<'a, C: Context> Writer for BufferCollector<'a, C> { #[inline] - fn write_bytes( &mut self, slice: &[u8] ) -> Result< (), C::Error > { - let buffer = self.buffer.get_mut( self.position..self.position + slice.len() ).ok_or_else( error_end_of_output_buffer )?; - buffer.copy_from_slice( slice ); + fn write_bytes(&mut self, slice: &[u8]) -> Result<(), C::Error> { + let buffer = self + .buffer + .get_mut(self.position..self.position + slice.len()) + .ok_or_else(error_end_of_output_buffer)?; + buffer.copy_from_slice(slice); self.position += slice.len(); Ok(()) } #[inline] - fn context( &self ) -> &C { + fn context(&self) -> &C { &self.context } #[inline] - fn context_mut( &mut self ) -> &mut C { + fn context_mut(&mut self) -> &mut C { &mut self.context } #[inline(always)] - fn can_write_at_least( &self, size: usize ) -> Option< bool > { - Some( self.buffer.get( self.position..self.position + size ).is_some() ) + fn can_write_at_least(&self, size: usize) -> Option { + Some( + self.buffer + .get(self.position..self.position + size) + .is_some(), + ) } } -struct WritingCollector< C: Context, T: Write > { +struct WritingCollector { context: C, - writer: T + writer: T, } -impl< C: Context, T: Write > Writer< C > for WritingCollector< C, T > { +impl Writer for WritingCollector { #[inline] - fn write_bytes( &mut self, slice: &[u8] ) -> Result< (), C::Error > { - self.writer.write_all( slice ).map_err( |error| { - let error = Error::from_io_error( error ); - >::from( error ) + fn write_bytes(&mut self, slice: &[u8]) -> Result<(), C::Error> { + self.writer.write_all(slice).map_err(|error| { + let error = Error::from_io_error(error); + >::from(error) }) } #[inline] - fn context( &self ) -> &C { + fn context(&self) -> &C { &self.context } #[inline] - fn context_mut( &mut self ) -> &mut C { + fn context_mut(&mut self) -> &mut C { &mut self.context } } struct SizeCalculatorCollector { - size: usize + size: usize, } -impl< C: Context > Writer< C > for SizeCalculatorCollector { +impl Writer for SizeCalculatorCollector { #[inline] - fn write_bytes( &mut self, slice: &[u8] ) -> Result< (), C::Error > { + fn write_bytes(&mut self, slice: &[u8]) -> Result<(), C::Error> { self.size += slice.len(); Ok(()) } #[inline] - fn write_u8( &mut self, _: u8 ) -> Result< (), C::Error > { + fn write_u8(&mut self, _: u8) -> Result<(), C::Error> { self.size += 1; Ok(()) } #[inline] - fn write_u16( &mut self, _: u16 ) -> Result< (), C::Error > { + fn write_u16(&mut self, _: u16) -> Result<(), C::Error> { self.size += 2; Ok(()) } #[inline] - fn write_u32( &mut self, _: u32 ) -> Result< (), C::Error > { + fn write_u32(&mut self, _: u32) -> Result<(), C::Error> { self.size += 4; Ok(()) } #[inline] - fn write_u64( &mut self, _: u64 ) -> Result< (), C::Error > { + fn write_u64(&mut self, _: u64) -> Result<(), C::Error> { self.size += 8; Ok(()) } #[inline] - fn write_u128( &mut self, _: u128 ) -> Result< (), C::Error > { + fn write_u128(&mut self, _: u128) -> Result<(), C::Error> { self.size += 16; Ok(()) } #[inline] - fn endianness( &self ) -> Endianness { + fn endianness(&self) -> Endianness { Endianness::NATIVE } #[inline] - fn context( &self ) -> &C { + fn context(&self) -> &C { panic!(); } #[inline] - fn context_mut( &mut self ) -> &mut C { + fn context_mut(&mut self) -> &mut C { panic!(); } } -pub trait Writable< C: Context > { - fn write_to< T: ?Sized + Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error >; +pub trait Writable { + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error>; #[inline] - fn write_to_buffer( &self, buffer: &mut [u8] ) -> Result< (), C::Error > where Self: DefaultContext< Context = C >, C: Default { - self.write_to_buffer_with_ctx( Default::default(), buffer ) + fn write_to_buffer(&self, buffer: &mut [u8]) -> Result<(), C::Error> + where + Self: DefaultContext, + C: Default, + { + self.write_to_buffer_with_ctx(Default::default(), buffer) } - fn write_to_vec( &self ) -> Result< Vec< u8 >, C::Error > where Self: DefaultContext< Context = C >, C: Default { - self.write_to_vec_with_ctx( Default::default() ) + fn write_to_vec(&self) -> Result, C::Error> + where + Self: DefaultContext, + C: Default, + { + self.write_to_vec_with_ctx(Default::default()) } #[inline] - fn write_to_stream< S: Write >( &self, stream: S ) -> Result< (), C::Error > where Self: DefaultContext< Context = C >, C: Default { - self.write_to_stream_with_ctx( Default::default(), stream ) + fn write_to_stream(&self, stream: S) -> Result<(), C::Error> + where + Self: DefaultContext, + C: Default, + { + self.write_to_stream_with_ctx(Default::default(), stream) } #[inline] - fn write_to_file( &self, path: impl AsRef< Path > ) -> Result< (), C::Error > where Self: DefaultContext< Context = C >, C: Default { - self.write_to_file_with_ctx( Default::default(), path ) + fn write_to_file(&self, path: impl AsRef) -> Result<(), C::Error> + where + Self: DefaultContext, + C: Default, + { + self.write_to_file_with_ctx(Default::default(), path) } #[inline] - fn write_to_buffer_with_ctx( &self, mut context: C, buffer: &mut [u8] ) -> Result< (), C::Error > { - self.write_to_buffer_with_ctx_mut( &mut context, buffer ) + fn write_to_buffer_with_ctx(&self, mut context: C, buffer: &mut [u8]) -> Result<(), C::Error> { + self.write_to_buffer_with_ctx_mut(&mut context, buffer) } #[inline] - fn write_to_buffer_with_ctx_mut( &self, context: &mut C, buffer: &mut [u8] ) -> Result< (), C::Error > { + fn write_to_buffer_with_ctx_mut( + &self, + context: &mut C, + buffer: &mut [u8], + ) -> Result<(), C::Error> { let bytes_needed = self.bytes_needed()?; let buffer_length = buffer.len(); - let buffer = buffer.get_mut( 0..bytes_needed ).ok_or_else( || error_output_buffer_is_too_small( buffer_length, bytes_needed ) )?; + let buffer = buffer + .get_mut(0..bytes_needed) + .ok_or_else(|| error_output_buffer_is_too_small(buffer_length, bytes_needed))?; let mut writer = BufferCollector { context, buffer, - position: 0 + position: 0, }; - self.write_to( &mut writer )?; + self.write_to(&mut writer)?; Ok(()) } #[inline] - fn write_to_vec_with_ctx( &self, mut context: C ) -> Result< Vec< u8 >, C::Error > { - self.write_to_vec_with_ctx_mut( &mut context ) + fn write_to_vec_with_ctx(&self, mut context: C) -> Result, C::Error> { + self.write_to_vec_with_ctx_mut(&mut context) } #[inline] - fn write_to_vec_with_ctx_mut( &self, context: &mut C ) -> Result< Vec< u8 >, C::Error > { + fn write_to_vec_with_ctx_mut(&self, context: &mut C) -> Result, C::Error> { let capacity = self.bytes_needed()?; - let mut vec = Vec::with_capacity( capacity ); + let mut vec = Vec::with_capacity(capacity); unsafe { - vec.set_len( capacity ); + vec.set_len(capacity); } let mut writer = BufferCollector { context, buffer: vec.as_mut_slice(), - position: 0 + position: 0, }; - self.write_to( &mut writer )?; + self.write_to(&mut writer)?; let position = writer.position; unsafe { - vec.set_len( position ); + vec.set_len(position); } - debug_assert_eq!( position, capacity ); - Ok( vec ) + debug_assert_eq!(position, capacity); + Ok(vec) } #[inline] - fn write_to_stream_with_ctx< S: Write >( &self, context: C, stream: S ) -> Result< (), C::Error > { + fn write_to_stream_with_ctx(&self, context: C, stream: S) -> Result<(), C::Error> { let mut writer = WritingCollector { context, - writer: stream + writer: stream, }; - self.write_to( &mut writer ) + self.write_to(&mut writer) } #[inline] - fn write_to_file_with_ctx( &self, context: C, path: impl AsRef< Path > ) -> Result< (), C::Error > { - let stream = File::create( path ).map_err( |error| { - let error = Error::from_io_error( error ); - >::from( error ) + fn write_to_file_with_ctx(&self, context: C, path: impl AsRef) -> Result<(), C::Error> { + let stream = File::create(path).map_err(|error| { + let error = Error::from_io_error(error); + >::from(error) })?; - let stream = io::BufWriter::new( stream ); - self.write_to_stream_with_ctx( context, stream ) + let stream = io::BufWriter::new(stream); + self.write_to_stream_with_ctx(context, stream) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - let mut writer = SizeCalculatorCollector { - size: 0 - }; + fn bytes_needed(&self) -> Result { + let mut writer = SizeCalculatorCollector { size: 0 }; - self.write_to( &mut writer )?; - Ok( writer.size ) + self.write_to(&mut writer)?; + Ok(writer.size) } // Since specialization is not stable yet we do it this way. @@ -240,7 +261,10 @@ pub trait Writable< C: Context > { #[doc(hidden)] #[inline] - unsafe fn speedy_slice_as_bytes( _: &[Self] ) -> &[u8] where Self: Sized { + unsafe fn speedy_slice_as_bytes(_: &[Self]) -> &[u8] + where + Self: Sized, + { panic!(); } } diff --git a/src/writable_impl.rs b/src/writable_impl.rs index f19858d..00a01b2 100644 --- a/src/writable_impl.rs +++ b/src/writable_impl.rs @@ -1,8 +1,8 @@ -use std::mem; use std::borrow::{Cow, ToOwned}; -use std::ops::Range; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::hash::Hash; +use std::mem; +use std::ops::Range; use crate::endianness::Endianness; use crate::writable::Writable; @@ -12,111 +12,115 @@ use crate::context::Context; use crate::private::write_length; -impl< C, K, V > Writable< C > for BTreeMap< K, V > - where C: Context, - K: Writable< C >, - V: Writable< C > +impl Writable for BTreeMap +where + C: Context, + K: Writable, + V: Writable, { #[inline] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - write_length( self.len(), writer )?; - writer.write_collection( self.iter() ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + write_length(self.len(), writer)?; + writer.write_collection(self.iter()) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - unsafe_is_length!( self.len() ); + fn bytes_needed(&self) -> Result { + unsafe_is_length!(self.len()); - let mut count = mem::size_of::< u32 >(); + let mut count = mem::size_of::(); for (key, value) in self { count += key.bytes_needed()? + value.bytes_needed()?; } - Ok( count ) + Ok(count) } } -impl< C, T > Writable< C > for BTreeSet< T > - where C: Context, - T: Writable< C > +impl Writable for BTreeSet +where + C: Context, + T: Writable, { #[inline] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - write_length( self.len(), writer )?; - writer.write_collection( self.iter() ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + write_length(self.len(), writer)?; + writer.write_collection(self.iter()) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - unsafe_is_length!( self.len() ); + fn bytes_needed(&self) -> Result { + unsafe_is_length!(self.len()); - let mut count = mem::size_of::< u32 >(); + let mut count = mem::size_of::(); for value in self { count += value.bytes_needed()?; } - Ok( count ) + Ok(count) } } -impl< C, K, V, S > Writable< C > for HashMap< K, V, S > - where C: Context, - K: Writable< C >, - V: Writable< C > +impl Writable for HashMap +where + C: Context, + K: Writable, + V: Writable, { #[inline] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - write_length( self.len(), writer )?; - writer.write_collection( self.iter() ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + write_length(self.len(), writer)?; + writer.write_collection(self.iter()) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - unsafe_is_length!( self.len() ); + fn bytes_needed(&self) -> Result { + unsafe_is_length!(self.len()); - let mut count = mem::size_of::< u32 >(); + let mut count = mem::size_of::(); for (key, value) in self { count += key.bytes_needed()? + value.bytes_needed()?; } - Ok( count ) + Ok(count) } } -impl< C, T, S > Writable< C > for HashSet< T, S > - where C: Context, - T: Writable< C > +impl Writable for HashSet +where + C: Context, + T: Writable, { #[inline] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - write_length( self.len(), writer )?; - writer.write_collection( self.iter() ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + write_length(self.len(), writer)?; + writer.write_collection(self.iter()) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - unsafe_is_length!( self.len() ); + fn bytes_needed(&self) -> Result { + unsafe_is_length!(self.len()); - let mut count = mem::size_of::< u32 >(); + let mut count = mem::size_of::(); for value in self { count += value.bytes_needed()?; } - Ok( count ) + Ok(count) } } macro_rules! impl_for_primitive { ($type:ty, $write_name:ident) => { - impl< C: Context > Writable< C > for $type { + impl Writable for $type { #[inline(always)] - fn write_to< T: ?Sized + Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error > { - writer.$write_name( *self ) + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error> { + writer.$write_name(*self) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Ok( mem::size_of::< Self >() ) + fn bytes_needed(&self) -> Result { + Ok(mem::size_of::()) } #[doc(hidden)] @@ -127,125 +131,131 @@ macro_rules! impl_for_primitive { #[doc(hidden)] #[inline(always)] - unsafe fn speedy_slice_as_bytes( slice: &[Self] ) -> &[u8] where Self: Sized { + unsafe fn speedy_slice_as_bytes(slice: &[Self]) -> &[u8] + where + Self: Sized, + { unsafe { - std::slice::from_raw_parts( slice.as_ptr() as *const u8, slice.len() * mem::size_of::< Self >() ) + std::slice::from_raw_parts( + slice.as_ptr() as *const u8, + slice.len() * mem::size_of::(), + ) } } } - } + }; } -impl_for_primitive!( i8, write_i8 ); -impl_for_primitive!( i16, write_i16 ); -impl_for_primitive!( i32, write_i32 ); -impl_for_primitive!( i64, write_i64 ); -impl_for_primitive!( i128, write_i128 ); -impl_for_primitive!( u8, write_u8 ); -impl_for_primitive!( u16, write_u16 ); -impl_for_primitive!( u32, write_u32 ); -impl_for_primitive!( u64, write_u64 ); -impl_for_primitive!( u128, write_u128 ); -impl_for_primitive!( f32, write_f32 ); -impl_for_primitive!( f64, write_f64 ); +impl_for_primitive!(i8, write_i8); +impl_for_primitive!(i16, write_i16); +impl_for_primitive!(i32, write_i32); +impl_for_primitive!(i64, write_i64); +impl_for_primitive!(i128, write_i128); +impl_for_primitive!(u8, write_u8); +impl_for_primitive!(u16, write_u16); +impl_for_primitive!(u32, write_u32); +impl_for_primitive!(u64, write_u64); +impl_for_primitive!(u128, write_u128); +impl_for_primitive!(f32, write_f32); +impl_for_primitive!(f64, write_f64); -impl< C: Context > Writable< C > for usize { +impl Writable for usize { #[inline] - fn write_to< T: ?Sized + Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error > { - writer.write_u64( *self as u64 ) + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error> { + writer.write_u64(*self as u64) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Ok( mem::size_of::< u64 >() ) + fn bytes_needed(&self) -> Result { + Ok(mem::size_of::()) } } -impl< C: Context > Writable< C > for bool { +impl Writable for bool { #[inline] - fn write_to< T: ?Sized + Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error > { - writer.write_u8( if *self { 1 } else { 0 } ) + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error> { + writer.write_u8(if *self { 1 } else { 0 }) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Ok( 1 ) + fn bytes_needed(&self) -> Result { + Ok(1) } } -impl< C: Context > Writable< C > for char { +impl Writable for char { #[inline] - fn write_to< T: ?Sized + Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error > { - writer.write_u32( *self as u32 ) + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error> { + writer.write_u32(*self as u32) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Ok( mem::size_of::< u32 >() ) + fn bytes_needed(&self) -> Result { + Ok(mem::size_of::()) } } -impl< C: Context > Writable< C > for String { +impl Writable for String { #[inline] - fn write_to< T: ?Sized + Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error > { - self.as_bytes().write_to( writer ) + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error> { + self.as_bytes().write_to(writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Writable::< C >::bytes_needed( self.as_bytes() ) + fn bytes_needed(&self) -> Result { + Writable::::bytes_needed(self.as_bytes()) } } -impl< C: Context > Writable< C > for str { +impl Writable for str { #[inline] - fn write_to< T: ?Sized + Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error > { - self.as_bytes().write_to( writer ) + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error> { + self.as_bytes().write_to(writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Writable::< C >::bytes_needed( self.as_bytes() ) + fn bytes_needed(&self) -> Result { + Writable::::bytes_needed(self.as_bytes()) } } -impl< 'a, C: Context > Writable< C > for &'a str { +impl<'a, C: Context> Writable for &'a str { #[inline] - fn write_to< T: ?Sized + Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error > { - self.as_bytes().write_to( writer ) + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error> { + self.as_bytes().write_to(writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Writable::< C >::bytes_needed( self.as_bytes() ) + fn bytes_needed(&self) -> Result { + Writable::::bytes_needed(self.as_bytes()) } } -impl< 'r, C: Context > Writable< C > for Cow< 'r, str > { +impl<'r, C: Context> Writable for Cow<'r, str> { #[inline] - fn write_to< T: ?Sized + Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error > { - self.as_bytes().write_to( writer ) + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error> { + self.as_bytes().write_to(writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Writable::< C >::bytes_needed( self.as_bytes() ) + fn bytes_needed(&self) -> Result { + Writable::::bytes_needed(self.as_bytes()) } } -impl< C: Context, T: Writable< C > > Writable< C > for [T] { +impl> Writable for [T] { #[inline] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - write_length( self.len(), writer )?; - writer.write_slice( self ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + write_length(self.len(), writer)?; + writer.write_slice(self) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - unsafe_is_length!( self.len() ); + fn bytes_needed(&self) -> Result { + unsafe_is_length!(self.len()); if T::speedy_is_primitive() { - return Ok( 4 + self.len() * mem::size_of::< T >() ); + return Ok(4 + self.len() * mem::size_of::()); } let mut sum = 4; @@ -253,137 +263,161 @@ impl< C: Context, T: Writable< C > > Writable< C > for [T] { sum += element.bytes_needed()?; } - Ok( sum ) + Ok(sum) } } -impl< 'r, C: Context, T: Writable< C > > Writable< C > for Cow< 'r, [T] > where [T]: ToOwned { +impl<'r, C: Context, T: Writable> Writable for Cow<'r, [T]> +where + [T]: ToOwned, +{ #[inline] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - self.as_ref().write_to( writer ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + self.as_ref().write_to(writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Writable::< C >::bytes_needed( self.as_ref() ) + fn bytes_needed(&self) -> Result { + Writable::::bytes_needed(self.as_ref()) } } -impl< 'a, C: Context, T: Writable< C > > Writable< C > for &'a [T] where [T]: ToOwned { +impl<'a, C: Context, T: Writable> Writable for &'a [T] +where + [T]: ToOwned, +{ #[inline] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - <[T] as Writable< C >>::write_to( self, writer ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + <[T] as Writable>::write_to(self, writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - <[T] as Writable::< C >>::bytes_needed( self.as_ref() ) + fn bytes_needed(&self) -> Result { + <[T] as Writable>::bytes_needed(self.as_ref()) } } -impl< 'r, C, T > Writable< C > for Cow< 'r, HashSet< T > > where C: Context, T: Writable< C > + Clone + Hash + Eq { +impl<'r, C, T> Writable for Cow<'r, HashSet> +where + C: Context, + T: Writable + Clone + Hash + Eq, +{ #[inline] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - (&**self).write_to( writer ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + (&**self).write_to(writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Writable::< C >::bytes_needed( &**self ) + fn bytes_needed(&self) -> Result { + Writable::::bytes_needed(&**self) } } -impl< 'r, C, T > Writable< C > for Cow< 'r, BTreeSet< T > > where C: Context, T: Writable< C > + Clone + Ord { +impl<'r, C, T> Writable for Cow<'r, BTreeSet> +where + C: Context, + T: Writable + Clone + Ord, +{ #[inline] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - (&**self).write_to( writer ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + (&**self).write_to(writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Writable::< C >::bytes_needed( &**self ) + fn bytes_needed(&self) -> Result { + Writable::::bytes_needed(&**self) } } -impl< 'r, C, K, V > Writable< C > for Cow< 'r, HashMap< K, V > > where C: Context, K: Writable< C > + Clone + Hash + Eq, V: Writable< C > + Clone { +impl<'r, C, K, V> Writable for Cow<'r, HashMap> +where + C: Context, + K: Writable + Clone + Hash + Eq, + V: Writable + Clone, +{ #[inline] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - (&**self).write_to( writer ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + (&**self).write_to(writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Writable::< C >::bytes_needed( &**self ) + fn bytes_needed(&self) -> Result { + Writable::::bytes_needed(&**self) } } -impl< 'r, C, K, V > Writable< C > for Cow< 'r, BTreeMap< K, V > > where C: Context, K: Writable< C > + Clone + Ord, V: Writable< C > + Clone { +impl<'r, C, K, V> Writable for Cow<'r, BTreeMap> +where + C: Context, + K: Writable + Clone + Ord, + V: Writable + Clone, +{ #[inline] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - (&**self).write_to( writer ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + (&**self).write_to(writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Writable::< C >::bytes_needed( &**self ) + fn bytes_needed(&self) -> Result { + Writable::::bytes_needed(&**self) } } -impl< C: Context, T: Writable< C > > Writable< C > for Vec< T > { +impl> Writable for Vec { #[inline] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - self.as_slice().write_to( writer ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + self.as_slice().write_to(writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Writable::< C >::bytes_needed( self.as_slice() ) + fn bytes_needed(&self) -> Result { + Writable::::bytes_needed(self.as_slice()) } } -impl< C: Context, T: Writable< C > > Writable< C > for Range< T > { +impl> Writable for Range { #[inline] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - self.start.write_to( writer )?; - self.end.write_to( writer ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + self.start.write_to(writer)?; + self.end.write_to(writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Ok( Writable::< C >::bytes_needed( &self.start )? + Writable::< C >::bytes_needed( &self.end )? ) + fn bytes_needed(&self) -> Result { + Ok(Writable::::bytes_needed(&self.start)? + Writable::::bytes_needed(&self.end)?) } } -impl< C: Context, T: Writable< C > > Writable< C > for Option< T > { +impl> Writable for Option { #[inline] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - if let Some( ref value ) = *self { - writer.write_u8( 1 )?; - value.write_to( writer ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + if let Some(ref value) = *self { + writer.write_u8(1)?; + value.write_to(writer) } else { - writer.write_u8( 0 ) + writer.write_u8(0) } } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - if let Some( ref value ) = *self { - Ok( 1 + Writable::< C >::bytes_needed( value )? ) + fn bytes_needed(&self) -> Result { + if let Some(ref value) = *self { + Ok(1 + Writable::::bytes_needed(value)?) } else { - Ok( 1 ) + Ok(1) } } } -impl< C: Context > Writable< C > for () { +impl Writable for () { #[inline] - fn write_to< W: ?Sized + Writer< C > >( &self, _: &mut W ) -> Result< (), C::Error > { + fn write_to>(&self, _: &mut W) -> Result<(), C::Error> { Ok(()) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Ok( 0 ) + fn bytes_needed(&self) -> Result { + Ok(0) } } @@ -414,272 +448,341 @@ macro_rules! impl_for_tuple { } } -impl_for_tuple!( A0 ); -impl_for_tuple!( A0, A1 ); -impl_for_tuple!( A0, A1, A2 ); -impl_for_tuple!( A0, A1, A2, A3 ); -impl_for_tuple!( A0, A1, A2, A3, A4 ); -impl_for_tuple!( A0, A1, A2, A3, A4, A5 ); -impl_for_tuple!( A0, A1, A2, A3, A4, A5, A6 ); -impl_for_tuple!( A0, A1, A2, A3, A4, A5, A6, A7 ); -impl_for_tuple!( A0, A1, A2, A3, A4, A5, A6, A7, A8 ); -impl_for_tuple!( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9 ); -impl_for_tuple!( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 ); +impl_for_tuple!(A0); +impl_for_tuple!(A0, A1); +impl_for_tuple!(A0, A1, A2); +impl_for_tuple!(A0, A1, A2, A3); +impl_for_tuple!(A0, A1, A2, A3, A4); +impl_for_tuple!(A0, A1, A2, A3, A4, A5); +impl_for_tuple!(A0, A1, A2, A3, A4, A5, A6); +impl_for_tuple!(A0, A1, A2, A3, A4, A5, A6, A7); +impl_for_tuple!(A0, A1, A2, A3, A4, A5, A6, A7, A8); +impl_for_tuple!(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9); +impl_for_tuple!(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); -impl< C: Context > Writable< C > for Endianness { +impl Writable for Endianness { #[inline] - fn write_to< T: ?Sized + Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error > { + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error> { let value = match *self { Endianness::LittleEndian => 0, - Endianness::BigEndian => 1 + Endianness::BigEndian => 1, }; - writer.write_u8( value ) + writer.write_u8(value) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Ok( 1 ) + fn bytes_needed(&self) -> Result { + Ok(1) } } -impl< 'a, C, T > Writable< C > for &'a T where C: Context, T: Writable< C > { +impl<'a, C, T> Writable for &'a T +where + C: Context, + T: Writable, +{ #[inline(always)] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - (**self).write_to( writer ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + (**self).write_to(writer) } #[inline(always)] - fn bytes_needed( &self ) -> Result< usize, C::Error > { + fn bytes_needed(&self) -> Result { (**self).bytes_needed() } } -impl< 'a, C, T > Writable< C > for &'a mut T where C: Context, T: Writable< C > { +impl<'a, C, T> Writable for &'a mut T +where + C: Context, + T: Writable, +{ #[inline(always)] - fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > { - (**self).write_to( writer ) + fn write_to>(&self, writer: &mut W) -> Result<(), C::Error> { + (**self).write_to(writer) } #[inline(always)] - fn bytes_needed( &self ) -> Result< usize, C::Error > { + fn bytes_needed(&self) -> Result { (**self).bytes_needed() } } macro_rules! impl_for_non_zero { ($type:ident, $base_type:ty) => { - impl< C > Writable< C > for std::num::$type where C: Context { + impl Writable for std::num::$type + where + C: Context, + { #[inline] - fn write_to< W >( &self, writer: &mut W ) -> Result< (), C::Error > where W: ?Sized + Writer< C > { - self.get().write_to( writer ) + fn write_to(&self, writer: &mut W) -> Result<(), C::Error> + where + W: ?Sized + Writer, + { + self.get().write_to(writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Ok( mem::size_of::< $base_type >() ) + fn bytes_needed(&self) -> Result { + Ok(mem::size_of::<$base_type>()) } } - } + }; } -impl_for_non_zero!( NonZeroU8, u8 ); -impl_for_non_zero!( NonZeroU16, u16 ); -impl_for_non_zero!( NonZeroU32, u32 ); -impl_for_non_zero!( NonZeroU64, u64 ); -impl_for_non_zero!( NonZeroI8, i8 ); -impl_for_non_zero!( NonZeroI16, i16 ); -impl_for_non_zero!( NonZeroI32, i32 ); -impl_for_non_zero!( NonZeroI64, i64 ); +impl_for_non_zero!(NonZeroU8, u8); +impl_for_non_zero!(NonZeroU16, u16); +impl_for_non_zero!(NonZeroU32, u32); +impl_for_non_zero!(NonZeroU64, u64); +impl_for_non_zero!(NonZeroI8, i8); +impl_for_non_zero!(NonZeroI16, i16); +impl_for_non_zero!(NonZeroI32, i32); +impl_for_non_zero!(NonZeroI64, i64); macro_rules! impl_for_atomic { ($type:ident, $base_type:ty) => { - impl< C: Context > Writable< C > for std::sync::atomic::$type { + impl Writable for std::sync::atomic::$type { #[inline(always)] - fn write_to< T: ?Sized + Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error > { - writer.write_value( &self.load( std::sync::atomic::Ordering::SeqCst ) ) + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error> { + writer.write_value(&self.load(std::sync::atomic::Ordering::SeqCst)) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Ok( mem::size_of::< $base_type >() ) + fn bytes_needed(&self) -> Result { + Ok(mem::size_of::<$base_type>()) } } - } + }; } -impl_for_atomic!( AtomicI8, i8 ); -impl_for_atomic!( AtomicI16, i16 ); -impl_for_atomic!( AtomicI32, i32 ); -impl_for_atomic!( AtomicI64, i64 ); +impl_for_atomic!(AtomicI8, i8); +impl_for_atomic!(AtomicI16, i16); +impl_for_atomic!(AtomicI32, i32); +impl_for_atomic!(AtomicI64, i64); -impl_for_atomic!( AtomicU8, u8 ); -impl_for_atomic!( AtomicU16, u16 ); -impl_for_atomic!( AtomicU32, u32 ); -impl_for_atomic!( AtomicU64, u64 ); +impl_for_atomic!(AtomicU8, u8); +impl_for_atomic!(AtomicU16, u16); +impl_for_atomic!(AtomicU32, u32); +impl_for_atomic!(AtomicU64, u64); -impl< C > Writable< C > for std::net::Ipv4Addr where C: Context { +impl Writable for std::net::Ipv4Addr +where + C: Context, +{ #[inline] - fn write_to< W >( &self, writer: &mut W ) -> Result< (), C::Error > where W: ?Sized + Writer< C > { + fn write_to(&self, writer: &mut W) -> Result<(), C::Error> + where + W: ?Sized + Writer, + { let raw: u32 = (*self).into(); - writer.write_u32( raw ) + writer.write_u32(raw) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Ok( 4 ) + fn bytes_needed(&self) -> Result { + Ok(4) } } -impl< C > Writable< C > for std::net::Ipv6Addr where C: Context { +impl Writable for std::net::Ipv6Addr +where + C: Context, +{ #[inline] - fn write_to< W >( &self, writer: &mut W ) -> Result< (), C::Error > where W: ?Sized + Writer< C > { + fn write_to(&self, writer: &mut W) -> Result<(), C::Error> + where + W: ?Sized + Writer, + { let mut octets = self.octets(); if !writer.endianness().conversion_necessary() { octets.reverse(); } - writer.write_bytes( &octets ) + writer.write_bytes(&octets) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Ok( 16 ) + fn bytes_needed(&self) -> Result { + Ok(16) } } -impl< C > Writable< C > for std::net::IpAddr where C: Context { +impl Writable for std::net::IpAddr +where + C: Context, +{ #[inline] - fn write_to< W >( &self, writer: &mut W ) -> Result< (), C::Error > where W: ?Sized + Writer< C > { + fn write_to(&self, writer: &mut W) -> Result<(), C::Error> + where + W: ?Sized + Writer, + { match self { - std::net::IpAddr::V4( address ) => { - writer.write_u8( 0 )?; - address.write_to( writer ) - }, - std::net::IpAddr::V6( address ) => { - writer.write_u8( 1 )?; - address.write_to( writer ) + std::net::IpAddr::V4(address) => { + writer.write_u8(0)?; + address.write_to(writer) + } + std::net::IpAddr::V6(address) => { + writer.write_u8(1)?; + address.write_to(writer) } } } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { + fn bytes_needed(&self) -> Result { match self { - std::net::IpAddr::V4( address ) => Writable::< C >::bytes_needed( address ).map( |count| count + 1 ), - std::net::IpAddr::V6( address ) => Writable::< C >::bytes_needed( address ).map( |count| count + 1 ) + std::net::IpAddr::V4(address) => { + Writable::::bytes_needed(address).map(|count| count + 1) + } + std::net::IpAddr::V6(address) => { + Writable::::bytes_needed(address).map(|count| count + 1) + } } } } -impl< C > Writable< C > for std::time::Duration where C: Context { +impl Writable for std::time::Duration +where + C: Context, +{ #[inline] - fn write_to< W >( &self, writer: &mut W ) -> Result< (), C::Error > where W: ?Sized + Writer< C > { - writer.write_u64( self.as_secs() )?; - writer.write_u32( self.subsec_nanos() ) + fn write_to(&self, writer: &mut W) -> Result<(), C::Error> + where + W: ?Sized + Writer, + { + writer.write_u64(self.as_secs())?; + writer.write_u32(self.subsec_nanos()) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Ok( 12 ) + fn bytes_needed(&self) -> Result { + Ok(12) } } -impl< C > Writable< C > for std::time::SystemTime where C: Context { +impl Writable for std::time::SystemTime +where + C: Context, +{ #[inline] - fn write_to< W >( &self, writer: &mut W ) -> Result< (), C::Error > where W: ?Sized + Writer< C > { - let duration = self.duration_since( std::time::SystemTime::UNIX_EPOCH ).map_err( |_| crate::error::error_invalid_system_time() )?; - writer.write_value( &duration ) + fn write_to(&self, writer: &mut W) -> Result<(), C::Error> + where + W: ?Sized + Writer, + { + let duration = self + .duration_since(std::time::SystemTime::UNIX_EPOCH) + .map_err(|_| crate::error::error_invalid_system_time())?; + writer.write_value(&duration) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Ok( 12 ) + fn bytes_needed(&self) -> Result { + Ok(12) } } macro_rules! impl_for_array { ($count:tt) => { - impl< C, T > Writable< C > for [T; $count] where C: Context, T: Writable< C > { + impl Writable for [T; $count] + where + C: Context, + T: Writable, + { #[inline] - fn write_to< W >( &self, writer: &mut W ) -> Result< (), C::Error > where W: ?Sized + Writer< C > { + fn write_to(&self, writer: &mut W) -> Result<(), C::Error> + where + W: ?Sized + Writer, + { for item in self { - item.write_to( writer )?; + item.write_to(writer)?; } Ok(()) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { + fn bytes_needed(&self) -> Result { let mut size = 0; for item in self { - size += Writable::< C >::bytes_needed( item )?; + size += Writable::::bytes_needed(item)?; } - Ok( size ) + Ok(size) } } - } -} - -impl_for_array!( 1 ); -impl_for_array!( 2 ); -impl_for_array!( 3 ); -impl_for_array!( 4 ); -impl_for_array!( 5 ); -impl_for_array!( 6 ); -impl_for_array!( 7 ); -impl_for_array!( 8 ); -impl_for_array!( 9 ); -impl_for_array!( 10 ); -impl_for_array!( 11 ); -impl_for_array!( 12 ); -impl_for_array!( 13 ); -impl_for_array!( 14 ); -impl_for_array!( 15 ); -impl_for_array!( 16 ); - -impl< C, T > Writable< C > for Box< T > - where C: Context, - T: Writable< C > + }; +} + +impl_for_array!(1); +impl_for_array!(2); +impl_for_array!(3); +impl_for_array!(4); +impl_for_array!(5); +impl_for_array!(6); +impl_for_array!(7); +impl_for_array!(8); +impl_for_array!(9); +impl_for_array!(10); +impl_for_array!(11); +impl_for_array!(12); +impl_for_array!(13); +impl_for_array!(14); +impl_for_array!(15); +impl_for_array!(16); + +impl Writable for Box +where + C: Context, + T: Writable, { #[inline] - fn write_to< W >( &self, writer: &mut W ) -> Result< (), C::Error > where W: ?Sized + Writer< C > { - (**self).write_to( writer ) + fn write_to(&self, writer: &mut W) -> Result<(), C::Error> + where + W: ?Sized + Writer, + { + (**self).write_to(writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { + fn bytes_needed(&self) -> Result { (**self).bytes_needed() } } -impl< C, T > Writable< C > for Box< [T] > - where C: Context, - T: Writable< C > +impl Writable for Box<[T]> +where + C: Context, + T: Writable, { #[inline] - fn write_to< W >( &self, writer: &mut W ) -> Result< (), C::Error > where W: ?Sized + Writer< C > { - (**self).write_to( writer ) + fn write_to(&self, writer: &mut W) -> Result<(), C::Error> + where + W: ?Sized + Writer, + { + (**self).write_to(writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { + fn bytes_needed(&self) -> Result { (**self).bytes_needed() } } -impl< C > Writable< C > for Box< str > - where C: Context +impl Writable for Box +where + C: Context, { #[inline] - fn write_to< W >( &self, writer: &mut W ) -> Result< (), C::Error > where W: ?Sized + Writer< C > { + fn write_to(&self, writer: &mut W) -> Result<(), C::Error> + where + W: ?Sized + Writer, + { let value: &str = &**self; - value.write_to( writer ) + value.write_to(writer) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { + fn bytes_needed(&self) -> Result { let value: &str = &**self; - Writable::< C >::bytes_needed( value ) + Writable::::bytes_needed(value) } } diff --git a/src/writer.rs b/src/writer.rs index fa9bd25..164e1a5 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -2,127 +2,134 @@ use std::mem; use crate::context::Context; use crate::endianness::Endianness; -use crate::writable::Writable; use crate::varint::VarInt64; +use crate::writable::Writable; -pub trait Writer< C: Context > { - fn write_bytes( &mut self, slice: &[u8] ) -> Result< (), C::Error >; +pub trait Writer { + fn write_bytes(&mut self, slice: &[u8]) -> Result<(), C::Error>; - fn context( &self ) -> &C; - fn context_mut( &mut self ) -> &mut C; + fn context(&self) -> &C; + fn context_mut(&mut self) -> &mut C; #[inline(always)] - fn can_write_at_least( &self, _size: usize ) -> Option< bool > { + fn can_write_at_least(&self, _size: usize) -> Option { None } #[inline(always)] - fn write_u8( &mut self, value: u8 ) -> Result< (), C::Error > { - let slice = unsafe { std::slice::from_raw_parts( &value, 1 ) }; - self.write_bytes( slice ) + fn write_u8(&mut self, value: u8) -> Result<(), C::Error> { + let slice = unsafe { std::slice::from_raw_parts(&value, 1) }; + self.write_bytes(slice) } #[inline(always)] - fn write_u16( &mut self, mut value: u16 ) -> Result< (), C::Error > { - self.context().endianness().swap_u16( &mut value ); - let slice = unsafe { std::slice::from_raw_parts( &value as *const u16 as *const u8, 2 ) }; - self.write_bytes( slice ) + fn write_u16(&mut self, mut value: u16) -> Result<(), C::Error> { + self.context().endianness().swap_u16(&mut value); + let slice = unsafe { std::slice::from_raw_parts(&value as *const u16 as *const u8, 2) }; + self.write_bytes(slice) } #[inline(always)] - fn write_u32( &mut self, mut value: u32 ) -> Result< (), C::Error > { - self.context().endianness().swap_u32( &mut value ); - let slice = unsafe { std::slice::from_raw_parts( &value as *const u32 as *const u8, 4 ) }; - self.write_bytes( slice ) + fn write_u32(&mut self, mut value: u32) -> Result<(), C::Error> { + self.context().endianness().swap_u32(&mut value); + let slice = unsafe { std::slice::from_raw_parts(&value as *const u32 as *const u8, 4) }; + self.write_bytes(slice) } #[inline(always)] - fn write_u64( &mut self, mut value: u64 ) -> Result< (), C::Error > { - self.context().endianness().swap_u64( &mut value ); - let slice = unsafe { std::slice::from_raw_parts( &value as *const u64 as *const u8, 8 ) }; - self.write_bytes( slice ) + fn write_u64(&mut self, mut value: u64) -> Result<(), C::Error> { + self.context().endianness().swap_u64(&mut value); + let slice = unsafe { std::slice::from_raw_parts(&value as *const u64 as *const u8, 8) }; + self.write_bytes(slice) } #[inline(always)] - fn write_u128( &mut self, mut value: u128 ) -> Result< (), C::Error > { - self.context().endianness().swap_u128( &mut value ); - let slice = unsafe { std::slice::from_raw_parts( &value as *const u128 as *const u8, 16 ) }; - self.write_bytes( slice ) + fn write_u128(&mut self, mut value: u128) -> Result<(), C::Error> { + self.context().endianness().swap_u128(&mut value); + let slice = unsafe { std::slice::from_raw_parts(&value as *const u128 as *const u8, 16) }; + self.write_bytes(slice) } #[inline(always)] - fn write_i8( &mut self, value: i8 ) -> Result< (), C::Error > { - self.write_u8( value as u8 ) + fn write_i8(&mut self, value: i8) -> Result<(), C::Error> { + self.write_u8(value as u8) } #[inline(always)] - fn write_i16( &mut self, value: i16 ) -> Result< (), C::Error > { - self.write_u16( value as u16 ) + fn write_i16(&mut self, value: i16) -> Result<(), C::Error> { + self.write_u16(value as u16) } #[inline(always)] - fn write_i32( &mut self, value: i32 ) -> Result< (), C::Error > { - self.write_u32( value as u32 ) + fn write_i32(&mut self, value: i32) -> Result<(), C::Error> { + self.write_u32(value as u32) } #[inline(always)] - fn write_i64( &mut self, value: i64 ) -> Result< (), C::Error > { - self.write_u64( value as u64 ) + fn write_i64(&mut self, value: i64) -> Result<(), C::Error> { + self.write_u64(value as u64) } #[inline(always)] - fn write_i128( &mut self, value: i128 ) -> Result< (), C::Error > { - self.write_u128( value as u128 ) + fn write_i128(&mut self, value: i128) -> Result<(), C::Error> { + self.write_u128(value as u128) } #[inline(always)] - fn write_f32( &mut self, value: f32 ) -> Result< (), C::Error > { - self.write_u32( value.to_bits() ) + fn write_f32(&mut self, value: f32) -> Result<(), C::Error> { + self.write_u32(value.to_bits()) } #[inline(always)] - fn write_f64( &mut self, value: f64 ) -> Result< (), C::Error > { - self.write_u64( value.to_bits() ) + fn write_f64(&mut self, value: f64) -> Result<(), C::Error> { + self.write_u64(value.to_bits()) } #[inline(always)] - fn endianness( &self ) -> Endianness { + fn endianness(&self) -> Endianness { self.context().endianness() } #[inline(always)] - fn write_value< T: Writable< C > >( &mut self, item: &T ) -> Result< (), C::Error > { - item.write_to( self ) + fn write_value>(&mut self, item: &T) -> Result<(), C::Error> { + item.write_to(self) } #[inline] - fn write_slice< T >( &mut self, slice: &[T] ) -> Result< (), C::Error > - where T: Writable< C > + fn write_slice(&mut self, slice: &[T]) -> Result<(), C::Error> + where + T: Writable, { - if T::speedy_is_primitive() && (mem::size_of::< T >() == 1 || !self.endianness().conversion_necessary()) { - let bytes = unsafe { T::speedy_slice_as_bytes( slice ) }; - self.write_bytes( bytes ) + if T::speedy_is_primitive() + && (mem::size_of::() == 1 || !self.endianness().conversion_necessary()) + { + let bytes = unsafe { T::speedy_slice_as_bytes(slice) }; + self.write_bytes(bytes) } else { for value in slice { - self.write_value( value )?; + self.write_value(value)?; } Ok(()) } } #[inline] - fn write_collection< T >( &mut self, collection: impl IntoIterator< Item = T > ) -> Result< (), C::Error > - where T: Writable< C > + fn write_collection( + &mut self, + collection: impl IntoIterator, + ) -> Result<(), C::Error> + where + T: Writable, { for item in collection { - item.write_to( self )?; + item.write_to(self)?; } Ok(()) } #[inline] - fn write_u64_varint( &mut self, value: u64 ) -> Result< (), C::Error > { - VarInt64::from( value ).write_to( self ) + fn write_u64_varint(&mut self, value: u64) -> Result<(), C::Error> { + VarInt64::from(value).write_to(self) } } diff --git a/static-tests/src/lib.rs b/static-tests/src/lib.rs index e69de29..8b13789 100644 --- a/static-tests/src/lib.rs +++ b/static-tests/src/lib.rs @@ -0,0 +1 @@ + diff --git a/static-tests/tests/tests.rs b/static-tests/tests/tests.rs index bb63aae..78609c3 100644 --- a/static-tests/tests/tests.rs +++ b/static-tests/tests/tests.rs @@ -1,211 +1,227 @@ use { - static_test::{ - static_test - }, speedy::{ - Endianness, - Readable, - Writable, - - private::{ - ErrorKind, - get_error_kind - } + private::{get_error_kind, ErrorKind}, + Endianness, Readable, Writable, }, - std::{ - borrow::{ - Cow - } - } + static_test::static_test, + std::borrow::Cow, }; #[static_test] -fn read_u16_from_buffer_when_buffer_length_is_known_and_is_big_enough( slice: &[u8] ) { - assume!( slice.len() == 2 ); - static_assert!( u16::read_from_buffer_with_ctx( Endianness::NATIVE, slice ).is_ok() ); +fn read_u16_from_buffer_when_buffer_length_is_known_and_is_big_enough(slice: &[u8]) { + assume!(slice.len() == 2); + static_assert!(u16::read_from_buffer_with_ctx(Endianness::NATIVE, slice).is_ok()); } #[static_test] -fn read_u16_from_buffer_when_buffer_length_is_known_and_is_not_big_enough_1( slice: &[u8] ) { - assume!( slice.len() == 1 ); - static_assert!( u16::read_from_buffer_with_ctx( Endianness::NATIVE, slice ).is_err() ); +fn read_u16_from_buffer_when_buffer_length_is_known_and_is_not_big_enough_1(slice: &[u8]) { + assume!(slice.len() == 1); + static_assert!(u16::read_from_buffer_with_ctx(Endianness::NATIVE, slice).is_err()); } #[static_test] -fn read_u16_from_buffer_when_buffer_length_is_known_and_is_not_big_enough_2( slice: &[u8] ) { - assume!( slice.len() == 1 ); - match u16::read_from_buffer_with_ctx( Endianness::NATIVE, slice ) { - Ok( _ ) => static_unreachable!(), - Err( error ) => { - match get_error_kind( &error ) { - ErrorKind::InputBufferIsTooSmall { actual_size, expected_size } => { - static_assert!( *actual_size == 1 ); - static_assert!( *expected_size == 2 ); - }, - _ => static_unreachable!() +fn read_u16_from_buffer_when_buffer_length_is_known_and_is_not_big_enough_2(slice: &[u8]) { + assume!(slice.len() == 1); + match u16::read_from_buffer_with_ctx(Endianness::NATIVE, slice) { + Ok(_) => static_unreachable!(), + Err(error) => match get_error_kind(&error) { + ErrorKind::InputBufferIsTooSmall { + actual_size, + expected_size, + } => { + static_assert!(*actual_size == 1); + static_assert!(*expected_size == 2); } - } + _ => static_unreachable!(), + }, } } #[static_test] -fn read_vec_u8_from_buffer_when_buffer_length_is_known_and_is_not_big_enough( slice: &[u8] ) { - assume!( slice.len() == 3 ); - match Vec::< u8 >::read_from_buffer_with_ctx( Endianness::NATIVE, slice ) { - Ok( _ ) => {}, - Err( error ) => { - match get_error_kind( &error ) { - ErrorKind::InputBufferIsTooSmall { actual_size, expected_size } => { - static_assert!( *actual_size == 3 ); - static_assert!( *expected_size == 4 ); - }, - _ => static_unreachable!() +fn read_vec_u8_from_buffer_when_buffer_length_is_known_and_is_not_big_enough(slice: &[u8]) { + assume!(slice.len() == 3); + match Vec::::read_from_buffer_with_ctx(Endianness::NATIVE, slice) { + Ok(_) => {} + Err(error) => match get_error_kind(&error) { + ErrorKind::InputBufferIsTooSmall { + actual_size, + expected_size, + } => { + static_assert!(*actual_size == 3); + static_assert!(*expected_size == 4); } - } + _ => static_unreachable!(), + }, } } #[static_test] -fn read_vec_u8_from_buffer_when_buffer_length_is_not_known( slice: &[u8] ) { - match Vec::< u8 >::read_from_buffer_with_ctx( Endianness::NATIVE, slice ) { - Ok( _ ) => {}, - Err( error ) => { - match get_error_kind( &error ) { - ErrorKind::InputBufferIsTooSmall { expected_size, .. } => { - static_assert!( *expected_size == 4 ); - }, - ErrorKind::UnexpectedEndOfInput => {}, - _ => static_unreachable!() +fn read_vec_u8_from_buffer_when_buffer_length_is_not_known(slice: &[u8]) { + match Vec::::read_from_buffer_with_ctx(Endianness::NATIVE, slice) { + Ok(_) => {} + Err(error) => match get_error_kind(&error) { + ErrorKind::InputBufferIsTooSmall { expected_size, .. } => { + static_assert!(*expected_size == 4); } - } + ErrorKind::UnexpectedEndOfInput => {} + _ => static_unreachable!(), + }, } } #[static_test] -fn read_cow_u8_from_buffer_when_buffer_length_is_not_known( slice: &[u8] ) { - match Cow::< [u8] >::read_from_buffer_with_ctx( Endianness::NATIVE, slice ) { - Ok( _ ) => {}, - Err( error ) => { - match get_error_kind( &error ) { - ErrorKind::InputBufferIsTooSmall { expected_size, .. } => { - static_assert!( *expected_size == 4 ); - }, - ErrorKind::UnexpectedEndOfInput => {}, - _ => static_unreachable!() +fn read_cow_u8_from_buffer_when_buffer_length_is_not_known(slice: &[u8]) { + match Cow::<[u8]>::read_from_buffer_with_ctx(Endianness::NATIVE, slice) { + Ok(_) => {} + Err(error) => match get_error_kind(&error) { + ErrorKind::InputBufferIsTooSmall { expected_size, .. } => { + static_assert!(*expected_size == 4); } - } + ErrorKind::UnexpectedEndOfInput => {} + _ => static_unreachable!(), + }, } } #[static_test] -fn write_u16_to_buffer_when_buffer_length_is_known_and_there_is_enough_space( slice: &mut [u8], value: u16 ) { - assume!( slice.len() == 2 ); - static_assert!( value.write_to_buffer_with_ctx( Endianness::NATIVE, slice ).is_ok() ); +fn write_u16_to_buffer_when_buffer_length_is_known_and_there_is_enough_space( + slice: &mut [u8], + value: u16, +) { + assume!(slice.len() == 2); + static_assert!(value + .write_to_buffer_with_ctx(Endianness::NATIVE, slice) + .is_ok()); } #[static_test] -fn write_u16_to_buffer_when_buffer_length_is_known_and_there_is_not_enough_space_1( slice: &mut [u8], value: u16 ) { - assume!( slice.len() == 1 ); - static_assert!( value.write_to_buffer_with_ctx( Endianness::NATIVE, slice ).is_err() ); +fn write_u16_to_buffer_when_buffer_length_is_known_and_there_is_not_enough_space_1( + slice: &mut [u8], + value: u16, +) { + assume!(slice.len() == 1); + static_assert!(value + .write_to_buffer_with_ctx(Endianness::NATIVE, slice) + .is_err()); } #[static_test] -fn write_u16_to_buffer_when_buffer_length_is_known_and_there_is_not_enough_space_2( slice: &mut [u8], value: u16 ) { - assume!( slice.len() == 1 ); - match value.write_to_buffer_with_ctx( Endianness::NATIVE, slice ) { - Ok( _ ) => static_unreachable!(), - Err( error ) => { - match get_error_kind( &error ) { - ErrorKind::OutputBufferIsTooSmall { actual_size, expected_size } => { - static_assert!( *actual_size == 1 ); - static_assert!( *expected_size == 2 ); - }, - _ => static_unreachable!() +fn write_u16_to_buffer_when_buffer_length_is_known_and_there_is_not_enough_space_2( + slice: &mut [u8], + value: u16, +) { + assume!(slice.len() == 1); + match value.write_to_buffer_with_ctx(Endianness::NATIVE, slice) { + Ok(_) => static_unreachable!(), + Err(error) => match get_error_kind(&error) { + ErrorKind::OutputBufferIsTooSmall { + actual_size, + expected_size, + } => { + static_assert!(*actual_size == 1); + static_assert!(*expected_size == 2); } - } + _ => static_unreachable!(), + }, } } #[static_test] -fn write_vec_u8_to_buffer_when_both_lengths_are_known_and_there_is_enough_space( slice: &mut [u8], value: Vec< u8 > ) { - assume!( slice.len() == 5 ); - assume!( value.len() == 1 ); - static_assert!( value.write_to_buffer_with_ctx( Endianness::NATIVE, slice ).is_ok() ); -} - -#[static_test] -fn write_vec_u8_to_buffer_when_both_lengths_are_known_and_there_is_not_enough_space_1( slice: &mut [u8], value: Vec< u8 > ) { - assume!( slice.len() == 5 ); - assume!( value.len() == 2 ); - static_assert!( value.write_to_buffer_with_ctx( Endianness::NATIVE, slice ).is_err() ); -} - -#[static_test] -fn write_vec_u8_to_buffer_when_both_lengths_are_known_and_there_is_not_enough_space_2( slice: &mut [u8], value: Vec< u8 > ) { - assume!( slice.len() == 5 ); - assume!( value.len() == 2 ); - match value.write_to_buffer_with_ctx( Endianness::NATIVE, slice ) { - Ok( _ ) => static_unreachable!(), - Err( error ) => { - match get_error_kind( &error ) { - ErrorKind::OutputBufferIsTooSmall { actual_size, expected_size } => { - static_assert!( *actual_size == 5 ); - static_assert!( *expected_size == 6 ); - }, - _ => static_unreachable!() +fn write_vec_u8_to_buffer_when_both_lengths_are_known_and_there_is_enough_space( + slice: &mut [u8], + value: Vec, +) { + assume!(slice.len() == 5); + assume!(value.len() == 1); + static_assert!(value + .write_to_buffer_with_ctx(Endianness::NATIVE, slice) + .is_ok()); +} + +#[static_test] +fn write_vec_u8_to_buffer_when_both_lengths_are_known_and_there_is_not_enough_space_1( + slice: &mut [u8], + value: Vec, +) { + assume!(slice.len() == 5); + assume!(value.len() == 2); + static_assert!(value + .write_to_buffer_with_ctx(Endianness::NATIVE, slice) + .is_err()); +} + +#[static_test] +fn write_vec_u8_to_buffer_when_both_lengths_are_known_and_there_is_not_enough_space_2( + slice: &mut [u8], + value: Vec, +) { + assume!(slice.len() == 5); + assume!(value.len() == 2); + match value.write_to_buffer_with_ctx(Endianness::NATIVE, slice) { + Ok(_) => static_unreachable!(), + Err(error) => match get_error_kind(&error) { + ErrorKind::OutputBufferIsTooSmall { + actual_size, + expected_size, + } => { + static_assert!(*actual_size == 5); + static_assert!(*expected_size == 6); } - } + _ => static_unreachable!(), + }, } } #[static_test] -fn write_vec_u8_to_buffer_when_buffer_length_is_known_and_there_is_not_enough_space_1( slice: &mut [u8], value: Vec< u8 > ) { - assume!( slice.len() == 3 ); - static_assert!( value.write_to_buffer_with_ctx( Endianness::NATIVE, slice ).is_err() ); +fn write_vec_u8_to_buffer_when_buffer_length_is_known_and_there_is_not_enough_space_1( + slice: &mut [u8], + value: Vec, +) { + assume!(slice.len() == 3); + static_assert!(value + .write_to_buffer_with_ctx(Endianness::NATIVE, slice) + .is_err()); } #[static_test] -fn write_vec_u8_to_buffer_when_buffer_length_is_known_and_there_is_not_enough_space_2( slice: &mut [u8], value: Vec< u8 > ) { - assume!( slice.len() == 3 ); - match value.write_to_buffer_with_ctx( Endianness::NATIVE, slice ) { - Ok( _ ) => static_unreachable!(), - Err( error ) => { - match get_error_kind( &error ) { - ErrorKind::OutputBufferIsTooSmall { actual_size, .. } => { - static_assert!( *actual_size == 3 ); - } - _ => static_unreachable!() +fn write_vec_u8_to_buffer_when_buffer_length_is_known_and_there_is_not_enough_space_2( + slice: &mut [u8], + value: Vec, +) { + assume!(slice.len() == 3); + match value.write_to_buffer_with_ctx(Endianness::NATIVE, slice) { + Ok(_) => static_unreachable!(), + Err(error) => match get_error_kind(&error) { + ErrorKind::OutputBufferIsTooSmall { actual_size, .. } => { + static_assert!(*actual_size == 3); } - } + _ => static_unreachable!(), + }, } } #[static_test] -fn write_vec_u8_to_buffer_when_vec_length_is_known( slice: &mut [u8], value: Vec< u8 > ) { - assume!( value.len() == 2 ); - match value.write_to_buffer_with_ctx( Endianness::NATIVE, slice ) { - Ok( _ ) => {}, - Err( error ) => { - match get_error_kind( &error ) { - ErrorKind::OutputBufferIsTooSmall { expected_size, .. } => { - static_assert!( *expected_size == 6 ); - } - _ => static_unreachable!() +fn write_vec_u8_to_buffer_when_vec_length_is_known(slice: &mut [u8], value: Vec) { + assume!(value.len() == 2); + match value.write_to_buffer_with_ctx(Endianness::NATIVE, slice) { + Ok(_) => {} + Err(error) => match get_error_kind(&error) { + ErrorKind::OutputBufferIsTooSmall { expected_size, .. } => { + static_assert!(*expected_size == 6); } - } + _ => static_unreachable!(), + }, } } #[static_test] -fn write_vec_u8_to_buffer_when_no_lengths_are_known( slice: &mut [u8], value: Vec< u8 > ) { - match value.write_to_buffer_with_ctx( Endianness::NATIVE, slice ) { - Ok( _ ) => {}, - Err( error ) => { - match get_error_kind( &error ) { - ErrorKind::OutOfRangeLength => {}, - ErrorKind::OutputBufferIsTooSmall { .. } => {}, - _ => static_unreachable!() - } - } +fn write_vec_u8_to_buffer_when_no_lengths_are_known(slice: &mut [u8], value: Vec) { + match value.write_to_buffer_with_ctx(Endianness::NATIVE, slice) { + Ok(_) => {} + Err(error) => match get_error_kind(&error) { + ErrorKind::OutOfRangeLength => {} + ErrorKind::OutputBufferIsTooSmall { .. } => {} + _ => static_unreachable!(), + }, } } diff --git a/tests/serialization_tests.rs b/tests/serialization_tests.rs index 5350fb0..b521351 100644 --- a/tests/serialization_tests.rs +++ b/tests/serialization_tests.rs @@ -1,11 +1,11 @@ use std::borrow::Cow; -use std::ops::Range; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::fmt::Debug; use std::num::NonZeroU32; +use std::ops::Range; #[allow(unused_imports)] -use speedy::{Readable, Writable, Endianness}; +use speedy::{Endianness, Readable, Writable}; macro_rules! symmetric_tests { ($( @@ -397,11 +397,11 @@ struct DerivedStruct { /// A doc comment. a: u8, b: u16, - c: u32 + c: u32, } #[derive(PartialEq, Debug, Readable, Writable)] -struct DerivedTupleStruct( u8, u16, u32 ); +struct DerivedTupleStruct(u8, u16, u32); #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedUnitStruct; @@ -414,7 +414,7 @@ enum DerivedSimpleEnum { /// A doc comment. A, B = 10, - C + C, } #[derive(PartialEq, Debug, Readable, Writable)] @@ -422,7 +422,7 @@ enum DerivedSimpleEnum { enum DerivedSimpleEnumTagTypeU7 { A, B, - C = 0x7f + C = 0x7f, } #[derive(PartialEq, Debug, Readable, Writable)] @@ -430,7 +430,7 @@ enum DerivedSimpleEnumTagTypeU7 { enum DerivedSimpleEnumTagTypeU8 { A, B = 0xab, - C + C, } #[derive(PartialEq, Debug, Readable, Writable)] @@ -438,7 +438,7 @@ enum DerivedSimpleEnumTagTypeU8 { enum DerivedSimpleEnumTagTypeU16 { A, B = 0xabcd, - C + C, } #[derive(PartialEq, Debug, Readable, Writable)] @@ -446,7 +446,7 @@ enum DerivedSimpleEnumTagTypeU16 { enum DerivedSimpleEnumTagTypeU32 { A, B = 0xabcdef01, - C + C, } #[derive(PartialEq, Debug, Readable, Writable)] @@ -455,51 +455,54 @@ enum DerivedSimpleEnumTagTypeU32 { enum DerivedSimpleEnumTagTypeU64 { A, B = 0xabcdef0123456789_u64, - C + C, } #[derive(PartialEq, Debug, Readable, Writable)] #[speedy(tag_type = u64_varint)] enum DerivedSimpleEnumTagTypeVarInt64 { A, - B = 0x1234 + B = 0x1234, } #[derive(PartialEq, Debug, Readable, Writable)] enum DerivedEnum { A, - B( u8, u16, u32 ), + B(u8, u16, u32), C { /// A doc comment. a: u8, b: u16, - c: u32 - } + c: u32, + }, } #[derive(PartialEq, Debug, Readable, Writable)] -struct DerivedStructWithLifetimeBytes< 'a > { - bytes: Cow< 'a, [u8] > +struct DerivedStructWithLifetimeBytes<'a> { + bytes: Cow<'a, [u8]>, } #[derive(PartialEq, Debug, Readable, Writable)] -struct DerivedStructWithLifetimeStr< 'a > { - inner: Cow< 'a, str > +struct DerivedStructWithLifetimeStr<'a> { + inner: Cow<'a, str>, } #[derive(PartialEq, Debug, Readable, Writable)] -struct DerivedStructWithGenericCow< 'a, T: 'a + ToOwned + ?Sized > where ::Owned: Debug { - inner: Cow< 'a, T > +struct DerivedStructWithGenericCow<'a, T: 'a + ToOwned + ?Sized> +where + ::Owned: Debug, +{ + inner: Cow<'a, T>, } #[derive(PartialEq, Debug, Readable, Writable)] -struct DerivedStructWithGenericRef< 'a, T: 'a + ?Sized > { - inner: &'a T +struct DerivedStructWithGenericRef<'a, T: 'a + ?Sized> { + inner: &'a T, } #[derive(PartialEq, Debug, Readable, Writable)] -struct DerivedStructWithGeneric< T > { - inner: T +struct DerivedStructWithGeneric { + inner: T, } #[derive(PartialEq, Debug, Readable, Writable)] @@ -508,172 +511,168 @@ struct DerivedStructWithDefaultOnEof { #[speedy(default_on_eof)] b: u16, #[speedy(default_on_eof)] - c: u32 + c: u32, } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedRecursiveStruct { - inner: Vec< DerivedRecursiveStruct > + inner: Vec, } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithVecWithCount { length: u8, #[speedy(length = length * 2)] - data: Vec< bool > + data: Vec, } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithStringWithCount { length: u8, #[speedy(length = length * 2)] - data: String + data: String, } #[derive(PartialEq, Debug, Readable, Writable)] -struct DerivedStructWithCowSliceWithCount< 'a > { +struct DerivedStructWithCowSliceWithCount<'a> { length: u8, #[speedy(length = length * 2)] - data: Cow< 'a, [bool] > + data: Cow<'a, [bool]>, } #[derive(PartialEq, Debug, Readable, Writable)] -struct DerivedStructWithCowStrWithCount< 'a > { +struct DerivedStructWithCowStrWithCount<'a> { length: u8, #[speedy(length = length * 2)] - data: Cow< 'a, str > + data: Cow<'a, str>, } #[derive(Readable, Writable, PartialEq, Eq, Debug)] -struct DerivedRefSliceU8WithCount< 'a > { +struct DerivedRefSliceU8WithCount<'a> { length: u8, #[speedy(length = length * 2)] - data: &'a [u8] + data: &'a [u8], } #[derive(Readable, Writable, PartialEq, Eq, Debug)] -struct DerivedRefStrWithCount< 'a > { +struct DerivedRefStrWithCount<'a> { length: u8, #[speedy(length = length * 2)] - data: &'a str + data: &'a str, } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithHashMapWithCount { length: u8, #[speedy(length = length / 4)] - data: HashMap< u8, u8 > + data: HashMap, } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithBTreeMapWithCount { length: u8, #[speedy(length = length / 4)] - data: BTreeMap< u8, u8 > + data: BTreeMap, } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithHashSetWithCount { length: u8, #[speedy(length = length / 4)] - data: HashSet< u8 > + data: HashSet, } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithBTreeSetWithCount { length: u8, #[speedy(length = length / 4)] - data: BTreeSet< u8 > + data: BTreeSet, } #[derive(PartialEq, Debug, Readable, Writable)] -struct DerivedStructWithCowHashMapWithCount< 'a > { +struct DerivedStructWithCowHashMapWithCount<'a> { length: u8, #[speedy(length = length / 4)] - data: Cow< 'a, HashMap< u8, u8 > > + data: Cow<'a, HashMap>, } #[derive(PartialEq, Debug, Readable, Writable)] -struct DerivedStructWithCowBTreeMapWithCount< 'a > { +struct DerivedStructWithCowBTreeMapWithCount<'a> { length: u8, #[speedy(length = length / 4)] - data: Cow< 'a, BTreeMap< u8, u8 > > + data: Cow<'a, BTreeMap>, } #[derive(PartialEq, Debug, Readable, Writable)] -struct DerivedStructWithCowHashSetWithCount< 'a > { +struct DerivedStructWithCowHashSetWithCount<'a> { length: u8, #[speedy(length = length / 4)] - data: Cow< 'a, HashSet< u8 > > + data: Cow<'a, HashSet>, } #[derive(PartialEq, Debug, Readable, Writable)] -struct DerivedStructWithCowBTreeSetWithCount< 'a > { +struct DerivedStructWithCowBTreeSetWithCount<'a> { length: u8, #[speedy(length = length / 4)] - data: Cow< 'a, BTreeSet< u8 > > + data: Cow<'a, BTreeSet>, } #[derive(PartialEq, Debug, Readable, Writable)] -struct DerivedTupleStructWithVecWithCount( - u8, - #[speedy(length = t0 * 2)] - Vec< bool > -); +struct DerivedTupleStructWithVecWithCount(u8, #[speedy(length = t0 * 2)] Vec); #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithVecWithDefaultOnEof { #[speedy(default_on_eof)] - data: Vec< u8 > + data: Vec, } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithVecWithCountWithDefaultOnEof { length: u8, #[speedy(length = length, default_on_eof)] - data: Vec< u8 > + data: Vec, } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithVecWithLengthTypeU7 { #[speedy(length_type = u7)] - data: Vec< u8 > + data: Vec, } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithVecWithLengthTypeU8 { #[speedy(length_type = u8)] - data: Vec< u8 > + data: Vec, } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithVecWithLengthTypeU16 { #[speedy(length_type = u16)] - data: Vec< u8 > + data: Vec, } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithVecWithLengthTypeU32 { #[speedy(length_type = u32)] - data: Vec< u8 > + data: Vec, } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithVecWithLengthTypeU64 { #[speedy(length_type = u64)] - data: Vec< u8 > + data: Vec, } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithVecWithLengthTypeVarInt64 { #[speedy(length_type = u64_varint)] - data: Vec< u8 > + data: Vec, } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithOptionVecWithLengthTypeU16 { #[speedy(length_type = u16)] - data: Option< Vec< u8 > > + data: Option>, } #[derive(PartialEq, Debug, Readable, Writable)] @@ -681,12 +680,12 @@ struct DerivedStructWithOptionVecWithLengthTypeU16 { enum DerivedEnumWithCustomTag { #[speedy(tag = 20)] A = 10, - B + B, } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithOptionU16 { - data: Option< u16 > + data: Option, } #[derive(PartialEq, Debug, Readable, Writable)] @@ -694,77 +693,76 @@ struct DerivedStructWithSkippedField { a: u8, #[speedy(skip)] _b: u8, - c: u8 + c: u8, } mod inner { use speedy::{Readable, Writable}; #[derive(Readable, Writable)] - struct Private { - } + struct Private {} // This is here only to make sure it compiles. #[derive(Readable, Writable)] pub struct Public { - field: Vec< Private > + field: Vec, } } #[derive(Clone, PartialEq, Debug, Readable, Writable)] -struct Newtype( u16 ); +struct Newtype(u16); #[derive(PartialEq, Debug, Readable, Writable)] -struct DerivedStructWithArray< T > { - data: [T; 4] +struct DerivedStructWithArray { + data: [T; 4], } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithConstantPrefixString { #[speedy(constant_prefix = "ABC")] - value: () + value: (), } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithConstantPrefixByteString { #[speedy(constant_prefix = b"ABC")] - value: () + value: (), } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithConstantPrefixChar { #[speedy(constant_prefix = '苺')] - value: () + value: (), } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithConstantPrefixByte { #[speedy(constant_prefix = b'A')] - value: () + value: (), } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithConstantPrefixBoolTrue { #[speedy(constant_prefix = true)] - value: () + value: (), } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithConstantPrefixBoolFalse { #[speedy(constant_prefix = false)] - value: () + value: (), } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithConstantPrefixU8 { #[speedy(constant_prefix = 10_u8)] - value: () + value: (), } #[derive(PartialEq, Debug, Readable, Writable)] struct DerivedStructWithConstantPrefixI8 { #[speedy(constant_prefix = -1_i8)] - value: () + value: (), } #[derive(PartialEq, Debug, Readable, Writable)] @@ -772,183 +770,175 @@ struct DerivedStructWithConstantPrefixI8 { #[speedy(peek_tag)] enum DerivedEnumWithPeekTagU8 { #[speedy(tag = 1)] - One( u8 ), + One(u8), #[speedy(tag = 2)] - Two( u8 ) + Two(u8), } #[derive(PartialEq, Debug, Readable, Writable)] #[speedy(tag_type = u8)] enum DerivedRecursiveEnum { None, - Some( Box< DerivedRecursiveEnum > ) + Some(Box), } // This is here only to make sure it compiles. #[derive(PartialEq, Debug, Readable, Writable)] -struct DerivedStructWithTwoDifferentCows< 'a > { - a: Cow< 'a, BTreeMap< u8, u8 > >, - b: Cow< 'a, [u8] > +struct DerivedStructWithTwoDifferentCows<'a> { + a: Cow<'a, BTreeMap>, + b: Cow<'a, [u8]>, } #[derive(Readable, Writable)] -struct DerivedTupleStructWithGenericVec< T >( Vec< T > ); +struct DerivedTupleStructWithGenericVec(Vec); #[derive(Readable, Writable)] -struct DerivedTupleStructWithGenericHashMap< K, V >( HashMap< K, V > ) where K: std::hash::Hash + Eq; +struct DerivedTupleStructWithGenericHashMap(HashMap) +where + K: std::hash::Hash + Eq; #[derive(Readable, Writable)] -struct DerivedTupleStructWithGenericHashSet< T >( HashSet< T > ) where T: std::hash::Hash + Eq; +struct DerivedTupleStructWithGenericHashSet(HashSet) +where + T: std::hash::Hash + Eq; #[derive(Readable, Writable)] -struct DerivedTupleStructWithGenericBTreeMap< K, V >( BTreeMap< K, V > ) where K: Ord; +struct DerivedTupleStructWithGenericBTreeMap(BTreeMap) +where + K: Ord; #[derive(Readable, Writable)] -struct DerivedTupleStructWithGenericBTreeSet< T >( BTreeSet< T > ) where T: Ord; +struct DerivedTupleStructWithGenericBTreeSet(BTreeSet) +where + T: Ord; #[derive(Readable, Writable)] -struct DerivedTupleStructWithGenericCowHashMap< 'a, K, V >( Cow< 'a, HashMap< K, V > > ) where K: std::hash::Hash + Eq + Clone, V: Clone; +struct DerivedTupleStructWithGenericCowHashMap<'a, K, V>(Cow<'a, HashMap>) +where + K: std::hash::Hash + Eq + Clone, + V: Clone; #[derive(Readable, Writable)] -struct DerivedTupleStructWithGenericCowHashSet< 'a, T >( Cow< 'a, HashSet< T > > ) where T: std::hash::Hash + Eq + Clone; +struct DerivedTupleStructWithGenericCowHashSet<'a, T>(Cow<'a, HashSet>) +where + T: std::hash::Hash + Eq + Clone; #[derive(Readable, Writable)] -struct DerivedTupleStructWithGenericCowBTreeMap< 'a, K, V >( Cow< 'a, BTreeMap< K, V > > ) where K: Ord + Clone, V: Clone; +struct DerivedTupleStructWithGenericCowBTreeMap<'a, K, V>(Cow<'a, BTreeMap>) +where + K: Ord + Clone, + V: Clone; #[derive(Readable, Writable)] -struct DerivedTupleStructWithGenericCowBTreeSet< 'a, T >( Cow< 'a, BTreeSet< T > > ) where T: Ord + Clone; +struct DerivedTupleStructWithGenericCowBTreeSet<'a, T>(Cow<'a, BTreeSet>) +where + T: Ord + Clone; macro_rules! atomic_wrapper { ($name:ident, $base_ty:ident) => { #[derive(Debug, Readable, Writable)] - struct $name( std::sync::atomic::$name ); + struct $name(std::sync::atomic::$name); impl $name { - pub fn new( value: $base_ty ) -> Self { - $name( value.into() ) + pub fn new(value: $base_ty) -> Self { + $name(value.into()) } } impl PartialEq for $name { - fn eq( &self, rhs: &$name ) -> bool { - self.0.load( std::sync::atomic::Ordering::SeqCst ) == - rhs.0.load( std::sync::atomic::Ordering::SeqCst ) + fn eq(&self, rhs: &$name) -> bool { + self.0.load(std::sync::atomic::Ordering::SeqCst) + == rhs.0.load(std::sync::atomic::Ordering::SeqCst) } } - } + }; } -atomic_wrapper!( AtomicI8, i8 ); -atomic_wrapper!( AtomicU8, u8 ); -atomic_wrapper!( AtomicI16, i16 ); -atomic_wrapper!( AtomicU16, u16 ); -atomic_wrapper!( AtomicI32, i32 ); -atomic_wrapper!( AtomicU32, u32 ); -atomic_wrapper!( AtomicI64, i64 ); -atomic_wrapper!( AtomicU64, u64 ); +atomic_wrapper!(AtomicI8, i8); +atomic_wrapper!(AtomicU8, u8); +atomic_wrapper!(AtomicI16, i16); +atomic_wrapper!(AtomicU16, u16); +atomic_wrapper!(AtomicI32, i32); +atomic_wrapper!(AtomicU32, u32); +atomic_wrapper!(AtomicI64, i64); +atomic_wrapper!(AtomicU64, u64); #[derive(Readable, Writable, PartialEq, Eq, Debug)] #[repr(transparent)] -struct TransparentU8( u8 ); +struct TransparentU8(u8); #[derive(Copy, Clone, Readable, Writable, PartialEq, Eq, Debug)] #[repr(transparent)] -struct TransparentU16( u16 ); +struct TransparentU16(u16); #[derive(Readable, Writable, PartialEq, Eq, Debug)] #[repr(transparent)] -struct TransparentU32( u32 ); +struct TransparentU32(u32); #[derive(Readable, Writable, PartialEq, Eq, Debug)] #[repr(transparent)] -struct TransparentU128( u128 ); +struct TransparentU128(u128); #[derive(Readable, Writable, PartialEq, Eq, Debug)] -struct DerivedRefStr< 'a >( &'a str ); +struct DerivedRefStr<'a>(&'a str); #[derive(Readable, Writable, PartialEq, Eq, Debug)] -struct DerivedRefSliceU8< 'a >( &'a [u8] ); +struct DerivedRefSliceU8<'a>(&'a [u8]); #[derive(Readable, Writable, PartialEq, Eq, Debug)] -struct DerivedStringUntilEof( - #[speedy(length = ..)] - String -); +struct DerivedStringUntilEof(#[speedy(length = ..)] String); #[derive(Readable, Writable, PartialEq, Eq, Debug)] -struct DerivedVecUntilEof( - #[speedy(length = ..)] - Vec< u8 > -); +struct DerivedVecUntilEof(#[speedy(length = ..)] Vec); #[derive(Readable, Writable, PartialEq, Eq, Debug)] -struct DerivedCowSliceUntilEof< 'a >( - #[speedy(length = ..)] - Cow< 'a, [u8] > -); +struct DerivedCowSliceUntilEof<'a>(#[speedy(length = ..)] Cow<'a, [u8]>); #[derive(Readable, Writable, PartialEq, Eq, Debug)] -struct DerivedCowStrUntilEof< 'a >( - #[speedy(length = ..)] - Cow< 'a, str > -); +struct DerivedCowStrUntilEof<'a>(#[speedy(length = ..)] Cow<'a, str>); #[derive(Readable, Writable, PartialEq, Eq, Debug)] -struct DerivedBTreeSetUntilEof( - #[speedy(length = ..)] - BTreeSet< u16 > -); +struct DerivedBTreeSetUntilEof(#[speedy(length = ..)] BTreeSet); #[derive(Readable, Writable, PartialEq, Eq, Debug)] -struct DerivedRefSliceU8UntilEof< 'a >( - #[speedy(length = ..)] - &'a [u8] -); +struct DerivedRefSliceU8UntilEof<'a>(#[speedy(length = ..)] &'a [u8]); #[derive(Readable, Writable, PartialEq, Eq, Debug)] -struct DerivedRefStrUntilEof< 'a >( - #[speedy(length = ..)] - &'a str -); +struct DerivedRefStrUntilEof<'a>(#[speedy(length = ..)] &'a str); #[derive(Copy, Clone, Readable, Writable, PartialEq, Eq, Debug)] -struct DerivedRefSlicePackedTuple< 'a >( - &'a [DerivedPackedTuple] -); +struct DerivedRefSlicePackedTuple<'a>(&'a [DerivedPackedTuple]); #[derive(Copy, Clone, Readable, Writable, PartialEq, Eq, Debug)] -struct DerivedRefSlicePackedTupleUntilEof< 'a >( - #[speedy(length = ..)] - &'a [DerivedPackedTuple] -); +struct DerivedRefSlicePackedTupleUntilEof<'a>(#[speedy(length = ..)] &'a [DerivedPackedTuple]); #[derive(Copy, Clone, Readable, Writable, PartialEq, Eq, Debug)] #[repr(packed)] -struct DerivedPackedTuple( u16, u16 ); +struct DerivedPackedTuple(u16, u16); #[derive(Copy, Clone, Readable, Writable, PartialEq, Eq, Debug)] #[repr(packed)] -struct DerivedPackedRecursiveTuple( DerivedPackedTuple, DerivedPackedTuple ); +struct DerivedPackedRecursiveTuple(DerivedPackedTuple, DerivedPackedTuple); #[derive(Readable, Writable, PartialEq, Eq, Debug)] #[repr(C)] -struct DeriveCWithU8( u8 ); +struct DeriveCWithU8(u8); #[derive(Readable, Writable, PartialEq, Eq, Debug)] #[repr(C)] -struct DeriveCWithU16( u16 ); +struct DeriveCWithU16(u16); #[derive(Readable, Writable, PartialEq, Eq, Debug)] #[repr(C)] -struct DeriveCWithU16U16( u16, u16 ); +struct DeriveCWithU16U16(u16, u16); #[derive(Readable, Writable, PartialEq, Eq, Debug)] #[repr(C)] -struct DeriveCWithU16U8( u16, u8 ); +struct DeriveCWithU16U8(u16, u8); #[derive(Readable, Writable, PartialEq, Eq, Debug)] #[repr(C)] -struct DeriveCWithDeriveC( DeriveCWithU16 ); +struct DeriveCWithDeriveC(DeriveCWithU16); #[derive(Readable, Writable, PartialEq, Eq, Debug)] #[repr(packed)] @@ -964,20 +954,20 @@ struct DeriveCDummy; #[derive(Readable, Writable, PartialEq, Eq, Debug)] #[repr(transparent)] -pub struct DeriveVecGenericTransparent< T >( Vec< T > ); +pub struct DeriveVecGenericTransparent(Vec); #[derive(Readable, Writable, PartialEq, Eq, Debug)] #[repr(transparent)] -pub struct DeriveArrayTransparent( [u8; 16] ); +pub struct DeriveArrayTransparent([u8; 16]); #[derive(Copy, Clone, Readable, Writable, PartialEq, Eq, Debug)] #[repr(packed)] -struct PackedU16( u16 ); +struct PackedU16(u16); #[derive(Readable, Writable, PartialEq, Eq, Debug)] struct DerivedStructWithVarInt { #[speedy(varint)] - value: u64 + value: u64, } symmetric_tests! { @@ -2265,17 +2255,14 @@ symmetric_tests! { #[cfg(feature = "regex")] #[test] fn test_regex() { - use speedy::{ - Readable, - Writable - }; + use speedy::{Readable, Writable}; - let regex = regex::Regex::new( "[a-z]+" ).unwrap(); + let regex = regex::Regex::new("[a-z]+").unwrap(); let buffer = regex.write_to_vec().unwrap(); - assert_eq!( buffer, &[6, 0, 0, 0, b'[', b'a', b'-', b'z', b']', b'+'] ); + assert_eq!(buffer, &[6, 0, 0, 0, b'[', b'a', b'-', b'z', b']', b'+']); - let deserialized = regex::Regex::read_from_buffer( &buffer ).unwrap(); - assert_eq!( regex.as_str(), deserialized.as_str() ); + let deserialized = regex::Regex::read_from_buffer(&buffer).unwrap(); + assert_eq!(regex.as_str(), deserialized.as_str()); } #[cfg(feature = "uuid")] @@ -2288,44 +2275,81 @@ symmetric_tests! { } } - #[test] fn test_derived_struct_with_default_on_eof() { - use speedy::{ - Readable, - Endianness - }; + use speedy::{Endianness, Readable}; - let deserialized: DerivedStructWithDefaultOnEof = Readable::read_from_buffer_with_ctx( Endianness::LittleEndian, &[0xAA] ).unwrap(); - assert_eq!( deserialized, DerivedStructWithDefaultOnEof { a: 0xAA, b: 0, c: 0 } ); + let deserialized: DerivedStructWithDefaultOnEof = + Readable::read_from_buffer_with_ctx(Endianness::LittleEndian, &[0xAA]).unwrap(); + assert_eq!( + deserialized, + DerivedStructWithDefaultOnEof { + a: 0xAA, + b: 0, + c: 0 + } + ); - let deserialized: DerivedStructWithDefaultOnEof = Readable::read_from_buffer_with_ctx( Endianness::LittleEndian, &[0xAA, 0xBB] ).unwrap(); - assert_eq!( deserialized, DerivedStructWithDefaultOnEof { a: 0xAA, b: 0, c: 0 } ); + let deserialized: DerivedStructWithDefaultOnEof = + Readable::read_from_buffer_with_ctx(Endianness::LittleEndian, &[0xAA, 0xBB]).unwrap(); + assert_eq!( + deserialized, + DerivedStructWithDefaultOnEof { + a: 0xAA, + b: 0, + c: 0 + } + ); - let deserialized: DerivedStructWithDefaultOnEof = Readable::read_from_buffer_with_ctx( Endianness::LittleEndian, &[0xAA, 0xBB, 0xCC] ).unwrap(); - assert_eq!( deserialized, DerivedStructWithDefaultOnEof { a: 0xAA, b: 0xCCBB, c: 0 } ); + let deserialized: DerivedStructWithDefaultOnEof = + Readable::read_from_buffer_with_ctx(Endianness::LittleEndian, &[0xAA, 0xBB, 0xCC]).unwrap(); + assert_eq!( + deserialized, + DerivedStructWithDefaultOnEof { + a: 0xAA, + b: 0xCCBB, + c: 0 + } + ); - let deserialized: DerivedStructWithVecWithDefaultOnEof = Readable::read_from_buffer_with_ctx( Endianness::LittleEndian, &[] ).unwrap(); - assert_eq!( deserialized, DerivedStructWithVecWithDefaultOnEof { data: vec![] } ); + let deserialized: DerivedStructWithVecWithDefaultOnEof = + Readable::read_from_buffer_with_ctx(Endianness::LittleEndian, &[]).unwrap(); + assert_eq!( + deserialized, + DerivedStructWithVecWithDefaultOnEof { data: vec![] } + ); - let deserialized: DerivedStructWithVecWithCountWithDefaultOnEof = Readable::read_from_buffer_with_ctx( Endianness::LittleEndian, &[2, 0xAA, 0xBB] ).unwrap(); - assert_eq!( deserialized, DerivedStructWithVecWithCountWithDefaultOnEof { length: 2, data: vec![0xAA, 0xBB] } ); + let deserialized: DerivedStructWithVecWithCountWithDefaultOnEof = + Readable::read_from_buffer_with_ctx(Endianness::LittleEndian, &[2, 0xAA, 0xBB]).unwrap(); + assert_eq!( + deserialized, + DerivedStructWithVecWithCountWithDefaultOnEof { + length: 2, + data: vec![0xAA, 0xBB] + } + ); - let deserialized: DerivedStructWithVecWithCountWithDefaultOnEof = Readable::read_from_buffer_with_ctx( Endianness::LittleEndian, &[2, 0xAA] ).unwrap(); - assert_eq!( deserialized, DerivedStructWithVecWithCountWithDefaultOnEof { length: 2, data: vec![] } ); + let deserialized: DerivedStructWithVecWithCountWithDefaultOnEof = + Readable::read_from_buffer_with_ctx(Endianness::LittleEndian, &[2, 0xAA]).unwrap(); + assert_eq!( + deserialized, + DerivedStructWithVecWithCountWithDefaultOnEof { + length: 2, + data: vec![] + } + ); } #[test] fn test_length_mismatch_with_length_attribute() { - use speedy::{ - Endianness, - Writable - }; + use speedy::{Endianness, Writable}; let err = DerivedStructWithVecWithCount { length: 0, - data: vec![ true ] - }.write_to_vec_with_ctx( Endianness::LittleEndian ).unwrap_err(); + data: vec![true], + } + .write_to_vec_with_ctx(Endianness::LittleEndian) + .unwrap_err(); assert_eq!( err.to_string(), @@ -2335,108 +2359,109 @@ fn test_length_mismatch_with_length_attribute() { #[test] fn test_zero_non_zero() { - let error = NonZeroU32::read_from_buffer( &[0, 0, 0, 0] ).unwrap_err(); - match speedy::private::get_error_kind( &error ) { - speedy::private::ErrorKind::ZeroNonZero => {}, - error => panic!( "Unexpected error: {:?}", error ) + let error = NonZeroU32::read_from_buffer(&[0, 0, 0, 0]).unwrap_err(); + match speedy::private::get_error_kind(&error) { + speedy::private::ErrorKind::ZeroNonZero => {} + error => panic!("Unexpected error: {:?}", error), } } #[test] fn test_vec_with_length_type_u7_read_out_of_range_length() { - let error = DerivedStructWithVecWithLengthTypeU7::read_from_buffer( &[0x80] ).unwrap_err(); - match speedy::private::get_error_kind( &error ) { - speedy::private::ErrorKind::OutOfRangeLength => {}, - error => panic!( "Unexpected error: {:?}", error ) + let error = DerivedStructWithVecWithLengthTypeU7::read_from_buffer(&[0x80]).unwrap_err(); + match speedy::private::get_error_kind(&error) { + speedy::private::ErrorKind::OutOfRangeLength => {} + error => panic!("Unexpected error: {:?}", error), } } #[test] fn test_prefix_constant_mismatch() { - let error = DerivedStructWithConstantPrefixString::read_from_buffer( &[0x41, 0x42] ).unwrap_err(); - match speedy::private::get_error_kind( &error ) { - speedy::private::ErrorKind::InputBufferIsTooSmall { .. } => {}, - error => panic!( "Unexpected error: {:?}", error ) + let error = DerivedStructWithConstantPrefixString::read_from_buffer(&[0x41, 0x42]).unwrap_err(); + match speedy::private::get_error_kind(&error) { + speedy::private::ErrorKind::InputBufferIsTooSmall { .. } => {} + error => panic!("Unexpected error: {:?}", error), } - let error = DerivedStructWithConstantPrefixString::read_from_buffer( &[0x41, 0x42, 0x00] ).unwrap_err(); - match speedy::private::get_error_kind( &error ) { - speedy::private::ErrorKind::ExpectedConstant { .. } => {}, - error => panic!( "Unexpected error: {:?}", error ) + let error = + DerivedStructWithConstantPrefixString::read_from_buffer(&[0x41, 0x42, 0x00]).unwrap_err(); + match speedy::private::get_error_kind(&error) { + speedy::private::ErrorKind::ExpectedConstant { .. } => {} + error => panic!("Unexpected error: {:?}", error), } } #[test] fn test_minimum_bytes_needed() { - use speedy::{ - Readable, - Endianness - }; + use speedy::{Endianness, Readable}; - assert_eq!( >::minimum_bytes_needed(), 1 ); + assert_eq!( + >::minimum_bytes_needed(), + 1 + ); } #[test] fn test_derive_transparent() { - assert!( >::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); - assert!( !>::speedy_is_primitive() ); + assert!(>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); + assert!(!>::speedy_is_primitive()); - assert!( >::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); - assert!( !>::speedy_is_primitive() ); + assert!(>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); + assert!(!>::speedy_is_primitive()); } #[test] fn test_derive_packed() { - assert!( !>::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); - assert!( !>::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); + assert!(!>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); + assert!(!>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); - assert!( >::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); + assert!(>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); } #[test] fn test_derive_c() { - assert!( >::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); - assert!( !>::speedy_is_primitive() ); + assert!(>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); + assert!(!>::speedy_is_primitive()); - assert!( >::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); - assert!( !>::speedy_is_primitive() ); + assert!(>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); + assert!(!>::speedy_is_primitive()); } #[test] fn test_derive_primitive() { - assert!( >::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); - assert!( >::speedy_is_primitive() ); + assert!(>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); + assert!(>::speedy_is_primitive()); - assert!( !>::speedy_is_primitive() ); - assert!( !>::speedy_is_primitive() ); - assert!( !>::speedy_is_primitive() ); - assert!( !>::speedy_is_primitive() ); + assert!(!>::speedy_is_primitive()); + assert!(!>::speedy_is_primitive()); + assert!(!>::speedy_is_primitive()); + assert!(!>::speedy_is_primitive()); } #[derive(PartialEq, Eq, Debug)] -struct ManualU8( u8 ); +struct ManualU8(u8); -impl< 'a, C: speedy::Context > Readable< 'a, C > for ManualU8 { +impl<'a, C: speedy::Context> Readable<'a, C> for ManualU8 { #[inline] - fn read_from< R: speedy::Reader< 'a, C > >( reader: &mut R ) -> Result< Self, C::Error > { - Ok( ManualU8( reader.read_u8()? ) ) + fn read_from>(reader: &mut R) -> Result { + Ok(ManualU8(reader.read_u8()?)) } #[inline] @@ -2445,31 +2470,31 @@ impl< 'a, C: speedy::Context > Readable< 'a, C > for ManualU8 { } } -impl< C: speedy::Context > speedy::Writable< C > for ManualU8 { +impl speedy::Writable for ManualU8 { #[inline] - fn write_to< T: ?Sized + speedy::Writer< C > >( &self, writer: &mut T ) -> Result< (), C::Error > { - writer.write_u8( self.0 ) + fn write_to>(&self, writer: &mut T) -> Result<(), C::Error> { + writer.write_u8(self.0) } #[inline] - fn bytes_needed( &self ) -> Result< usize, C::Error > { - Ok( 1 ) + fn bytes_needed(&self) -> Result { + Ok(1) } } #[derive(Readable, Writable, PartialEq, Eq, Debug)] -struct NonTransparentU8( u8 ); +struct NonTransparentU8(u8); #[derive(Readable, Writable, PartialEq, Eq, Debug)] #[repr(transparent)] -struct TransparentNonZeroCopyable( Vec< u8 > ); +struct TransparentNonZeroCopyable(Vec); #[derive(Copy, Clone, Readable, Writable, PartialEq, Eq, Debug)] -struct NonZeroCopyable( u8 ); +struct NonZeroCopyable(u8); #[derive(Readable, Writable, PartialEq, Eq, Debug)] #[repr(packed)] -struct PackedNonZeroCopyable( NonZeroCopyable ); +struct PackedNonZeroCopyable(NonZeroCopyable); #[derive(Readable, Writable, PartialEq, Debug)] struct ThreeF32 { @@ -2517,99 +2542,116 @@ macro_rules! assert_impl { }; } -assert_not_impl!( (u8, u8), speedy::private::ZeroCopyable< () > ); -assert_not_impl!( Vec< u8 >, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( NonTransparentU8, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( TransparentNonZeroCopyable, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( NonZeroCopyable, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( PackedNonZeroCopyable, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( DerivedRefSlicePackedTuple, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( DerivedRefSlicePackedTupleUntilEof, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( &[DerivedPackedTuple], speedy::private::ZeroCopyable< () > ); -assert_not_impl!( u16, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( u32, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( u64, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( u128, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( i16, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( i32, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( i64, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( i128, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( f32, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( f64, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( TransparentU16, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( TransparentU32, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( TransparentU128, speedy::private::ZeroCopyable< () > ); -assert_not_impl!( &'static [u16], speedy::Readable< 'static, speedy::LittleEndian > ); - -assert_impl!( u8, speedy::private::ZeroCopyable< () > ); -assert_impl!( i8, speedy::private::ZeroCopyable< () > ); -assert_impl!( TransparentU8, speedy::private::ZeroCopyable< () > ); -assert_impl!( DerivedPackedTuple, speedy::private::ZeroCopyable< () > ); -assert_impl!( DerivedPackedRecursiveTuple, speedy::private::ZeroCopyable< () > ); -assert_impl!( &'static [PackedU16], speedy::Readable< 'static, speedy::LittleEndian > ); +assert_not_impl!((u8, u8), speedy::private::ZeroCopyable<()>); +assert_not_impl!(Vec, speedy::private::ZeroCopyable<()>); +assert_not_impl!(NonTransparentU8, speedy::private::ZeroCopyable<()>); +assert_not_impl!( + TransparentNonZeroCopyable, + speedy::private::ZeroCopyable<()> +); +assert_not_impl!(NonZeroCopyable, speedy::private::ZeroCopyable<()>); +assert_not_impl!(PackedNonZeroCopyable, speedy::private::ZeroCopyable<()>); +assert_not_impl!( + DerivedRefSlicePackedTuple, + speedy::private::ZeroCopyable<()> +); +assert_not_impl!( + DerivedRefSlicePackedTupleUntilEof, + speedy::private::ZeroCopyable<()> +); +assert_not_impl!(&[DerivedPackedTuple], speedy::private::ZeroCopyable<()>); +assert_not_impl!(u16, speedy::private::ZeroCopyable<()>); +assert_not_impl!(u32, speedy::private::ZeroCopyable<()>); +assert_not_impl!(u64, speedy::private::ZeroCopyable<()>); +assert_not_impl!(u128, speedy::private::ZeroCopyable<()>); +assert_not_impl!(i16, speedy::private::ZeroCopyable<()>); +assert_not_impl!(i32, speedy::private::ZeroCopyable<()>); +assert_not_impl!(i64, speedy::private::ZeroCopyable<()>); +assert_not_impl!(i128, speedy::private::ZeroCopyable<()>); +assert_not_impl!(f32, speedy::private::ZeroCopyable<()>); +assert_not_impl!(f64, speedy::private::ZeroCopyable<()>); +assert_not_impl!(TransparentU16, speedy::private::ZeroCopyable<()>); +assert_not_impl!(TransparentU32, speedy::private::ZeroCopyable<()>); +assert_not_impl!(TransparentU128, speedy::private::ZeroCopyable<()>); +assert_not_impl!( + &'static [u16], + speedy::Readable<'static, speedy::LittleEndian> +); + +assert_impl!(u8, speedy::private::ZeroCopyable<()>); +assert_impl!(i8, speedy::private::ZeroCopyable<()>); +assert_impl!(TransparentU8, speedy::private::ZeroCopyable<()>); +assert_impl!(DerivedPackedTuple, speedy::private::ZeroCopyable<()>); +assert_impl!( + DerivedPackedRecursiveTuple, + speedy::private::ZeroCopyable<()> +); +assert_impl!( + &'static [PackedU16], + speedy::Readable<'static, speedy::LittleEndian> +); #[test] fn test_incomplete_read_into_vec_triggers_drop_for_already_read_items() { use std::sync::atomic::{AtomicU64, Ordering}; - static COUNTER: AtomicU64 = AtomicU64::new( 0 ); + static COUNTER: AtomicU64 = AtomicU64::new(0); #[derive(Readable, Writable, PartialEq, Eq, Debug)] - struct WithDrop( ManualU8 ); + struct WithDrop(ManualU8); impl Drop for WithDrop { - fn drop( &mut self ) { - COUNTER.fetch_add( 1, Ordering::SeqCst ); + fn drop(&mut self) { + COUNTER.fetch_add(1, Ordering::SeqCst); } } #[derive(Readable, Writable, PartialEq, Eq, Debug)] - struct Struct( Vec< WithDrop > ); + struct Struct(Vec); - Struct::read_from_stream_unbuffered( &mut &[0, 0, 0, 10, 1, 2][..] ).unwrap_err(); - assert_eq!( COUNTER.load( Ordering::SeqCst ), 2 ); + Struct::read_from_stream_unbuffered(&mut &[0, 0, 0, 10, 1, 2][..]).unwrap_err(); + assert_eq!(COUNTER.load(Ordering::SeqCst), 2); } #[test] -fn test_incomplete_read_into_vec_does_not_trigger_drop_for_already_read_items_if_they_are_primitive() { +fn test_incomplete_read_into_vec_does_not_trigger_drop_for_already_read_items_if_they_are_primitive( +) { use std::sync::atomic::{AtomicU64, Ordering}; - static COUNTER: AtomicU64 = AtomicU64::new( 0 ); + static COUNTER: AtomicU64 = AtomicU64::new(0); #[derive(Readable, Writable, PartialEq, Eq, Debug)] - struct WithDrop( u8 ); + struct WithDrop(u8); impl Drop for WithDrop { - fn drop( &mut self ) { - COUNTER.fetch_add( 1, Ordering::SeqCst ); + fn drop(&mut self) { + COUNTER.fetch_add(1, Ordering::SeqCst); } } #[derive(Readable, Writable, PartialEq, Eq, Debug)] - struct Struct( Vec< WithDrop > ); + struct Struct(Vec); - Struct::read_from_stream_unbuffered( &mut &[0, 0, 0, 10, 1, 2][..] ).unwrap_err(); - assert_eq!( COUNTER.load( Ordering::SeqCst ), 0 ); + Struct::read_from_stream_unbuffered(&mut &[0, 0, 0, 10, 1, 2][..]).unwrap_err(); + assert_eq!(COUNTER.load(Ordering::SeqCst), 0); } #[test] fn test_zero_copy_cow_deserialization() { - let input: Vec< u8 > = vec![ - 2, 0, 0, 0, - 33, 0, - 100, 0, - ]; + let input: Vec = vec![2, 0, 0, 0, 33, 0, 100, 0]; - let value_borrowed: Cow< [u16] > = Readable::read_from_buffer_with_ctx( Endianness::LittleEndian, &input ).unwrap(); - let value_owned: Cow< [u16] > = Readable::read_from_buffer_copying_data_with_ctx( Endianness::LittleEndian, &input ).unwrap(); + let value_borrowed: Cow<[u16]> = + Readable::read_from_buffer_with_ctx(Endianness::LittleEndian, &input).unwrap(); + let value_owned: Cow<[u16]> = + Readable::read_from_buffer_copying_data_with_ctx(Endianness::LittleEndian, &input).unwrap(); match value_borrowed { - Cow::Owned( _ ) => panic!(), - Cow::Borrowed( value ) => assert_eq!( value, &[33, 100] ) + Cow::Owned(_) => panic!(), + Cow::Borrowed(value) => assert_eq!(value, &[33, 100]), } - std::mem::drop( input ); + std::mem::drop(input); match value_owned { - Cow::Owned( value ) => assert_eq!( value, &[33, 100] ), - Cow::Borrowed( _ ) => panic!() + Cow::Owned(value) => assert_eq!(value, &[33, 100]), + Cow::Borrowed(_) => panic!(), } }