Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@ readme = "README.md"
keywords = ["serialization"]
categories = ["encoding"]
description = "A fast binary serialization framework"
edition = "2018"
edition = "2021"

[dependencies]
memoffset = "0.7"
speedy-derive = { version = "= 0.8.3", path = "speedy-derive", optional = true }
chrono = { version = "0.4", optional = true }
glam = { version = ">= 0.15, <= 0.20", optional = true }
glam = { version = ">= 0.15, <= 0.22", optional = true }
smallvec = { version = "1", optional = true }
regex = { version = "1", optional = true, default-features = false }
uuid = {version = "1", optional = true, default-features = false }
indexmap = { version = "1", optional = true }

[dev-dependencies]
quickcheck = "0.9"
quickcheck = "1.0"
paste = "1"
tempfile = "3"

Expand Down
71 changes: 30 additions & 41 deletions speedy-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,22 +96,19 @@ fn possibly_uses_generic_ty( generic_types: &[&syn::Ident], ty: &syn::Type ) ->
}
})
},
syn::Type::Slice( syn::TypeSlice { elem, .. } ) => 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::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 ) {
if possibly_uses_generic_ty( generic_types, elem ) {
return true;
}

// This is probably too conservative.
match len {
syn::Expr::Lit( .. ) => false,
_ => true
}
!matches!(len, syn::Expr::Lit( .. ))
},
syn::Type::Never( .. ) => false,
_ => true
Expand Down Expand Up @@ -185,22 +182,19 @@ fn is_guaranteed_non_recursive( ty: &syn::Type ) -> bool {
_ => 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::Slice( syn::TypeSlice { elem, .. } ) => is_guaranteed_non_recursive( elem ),
syn::Type::Tuple( syn::TypeTuple { elems, .. } ) => elems.iter().all( is_guaranteed_non_recursive ),
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 ) {
if !is_guaranteed_non_recursive( elem ) {
return false;
}

// This is probably too conservative.
match len {
syn::Expr::Lit( .. ) => true,
_ => false
}
!matches!(len, syn::Expr::Lit( .. ))
},
syn::Type::Never( .. ) => true,
_ => false
Expand Down Expand Up @@ -672,11 +666,11 @@ struct Field< 'a > {
impl< 'a > Field< 'a > {
fn is_simple( &self ) -> bool {
parse_primitive_ty( self.raw_ty ).is_some() &&
self.default_on_eof == false &&
!self.default_on_eof &&
self.length.is_none() &&
self.length_type.is_none() &&
self.skip == false &&
self.varint == false &&
!self.skip &&
!self.varint &&
self.constant_prefix.is_none()
}

Expand Down Expand Up @@ -723,7 +717,7 @@ impl< 'a > Field< 'a > {
}

fn is_guaranteed_non_recursive( &self ) -> bool {
is_guaranteed_non_recursive( &self.raw_ty )
is_guaranteed_non_recursive( self.raw_ty )
}
}

Expand Down Expand Up @@ -814,7 +808,7 @@ impl syn::parse::Parse for FieldAttribute {
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::Bool( literal ) => vec![ u8::from(literal.value) ],
syn::Lit::Int( literal ) => {
if literal.suffix() == "u8" {
vec![ literal.base10_parse::< u8 >().unwrap() ]
Expand All @@ -832,7 +826,7 @@ impl syn::parse::Parse for FieldAttribute {
match literal {
syn::Lit::Int( literal ) => {
if literal.suffix() == "i8" {
vec![ (literal.base10_parse::< i8 >().unwrap() * -1) as u8 ]
vec![ -literal.base10_parse::< i8 >().unwrap() as u8 ]
} else if literal.suffix() == "u8" {
return generic_error()
} else {
Expand Down Expand Up @@ -1604,7 +1598,7 @@ fn readable_body< 'a >( types: &mut Vec< syn::Type >, st: &Struct< 'a > ) -> (To
field_names.push( name );
types.extend( field.bound_types() );

if let Some( minimum_bytes ) = get_minimum_bytes( &field ) {
if let Some( minimum_bytes ) = get_minimum_bytes( field ) {
minimum_bytes_needed.push( minimum_bytes );
}
}
Expand Down Expand Up @@ -1717,16 +1711,14 @@ fn write_field_body( field: &Field ) -> TokenStream {
Opt::Option( _ ) => write_option( body )
};

let body = if let Some( ref constant_prefix ) = field.constant_prefix {
if let Some( ref constant_prefix ) = field.constant_prefix {
quote! {{
_writer_.write_slice( #constant_prefix )?;
#body
}}
} else {
body
};

body
}
}

fn writable_body< 'a >( types: &mut Vec< syn::Type >, st: &Struct< 'a > ) -> (TokenStream, TokenStream) {
Expand All @@ -1737,7 +1729,7 @@ fn writable_body< 'a >( types: &mut Vec< syn::Type >, st: &Struct< 'a > ) -> (To
continue;
}

let write_value = write_field_body( &field );
let write_value = write_field_body( field );
types.extend( field.bound_types() );

field_names.push( field.var_name().clone() );
Expand Down Expand Up @@ -1777,7 +1769,7 @@ impl< 'a > Enum< 'a > {
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::U7 => 0b01111111_u64,
BasicType::U8 => std::u8::MAX as u64,
BasicType::U16 => std::u16::MAX as u64,
BasicType::U32 => std::u32::MAX as u64,
Expand Down Expand Up @@ -1862,7 +1854,6 @@ impl< 'a > Enum< 'a > {
quote! { #tag }
},
BasicType::U64 | BasicType::VarInt64 => {
let tag = tag as u64;
quote! { #tag }
}
};
Expand Down Expand Up @@ -2125,7 +2116,7 @@ fn impl_readable( input: syn::DeriveInput ) -> Result< TokenStream, syn::Error >
(reader_body, minimum_bytes, impl_primitive, impl_zerocopyable)
},
syn::Data::Enum( syn::DataEnum { variants, .. } ) => {
let enumeration = Enum::new( &name, &input.attrs, &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 {
Expand All @@ -2140,10 +2131,8 @@ 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 );
}
if variant.structure.kind != StructKind::Unit && variant.structure.is_guaranteed_non_recursive() {
variant_minimum_sizes.push( minimum_bytes );
}
}

Expand Down Expand Up @@ -2281,7 +2270,7 @@ 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 )?;
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 },
Expand Down
6 changes: 3 additions & 3 deletions src/readable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,12 +263,12 @@ impl< 'ctx, 'r, 'a, C: Context > Reader< 'r, C > for CopyingBufferReader< 'ctx,

#[inline(always)]
fn context( &self ) -> &C {
&self.context
self.context
}

#[inline(always)]
fn context_mut( &mut self ) -> &mut C {
&mut self.context
self.context
}
}

Expand All @@ -279,7 +279,7 @@ struct StreamReader< C: Context, S: Read > {
is_buffering: bool
}

impl< 'a, C, S > StreamReader< C, S > where C: Context, S: Read {
impl< C, S > StreamReader< C, S > where C: Context, S: Read {
#[inline(never)]
fn read_bytes_slow( &mut self, mut output: &mut [u8] ) -> Result< (), C::Error > {
if self.is_buffering && output.len() < self.buffer.capacity() {
Expand Down
2 changes: 1 addition & 1 deletion src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl< T > Iterator for RawCopyIter< T > {
#[inline(always)]
fn next( &mut self ) -> Option< Self::Item > {
if self.pointer.as_ptr() as *const T == self.end {
return None;
None
} else {
unsafe {
let old = self.pointer.as_ptr();
Expand Down
4 changes: 2 additions & 2 deletions src/writable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ impl< 'a, C: Context > Writer< C > for BufferCollector< 'a, C > {

#[inline]
fn context( &self ) -> &C {
&self.context
self.context
}

#[inline]
fn context_mut( &mut self ) -> &mut C {
&mut self.context
self.context
}

#[inline(always)]
Expand Down
16 changes: 8 additions & 8 deletions src/writable_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ impl< C: Context > Writable< C > for usize {
impl< C: Context > Writable< C > 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 } )
writer.write_u8( u8::from(*self) )
}

#[inline]
Expand Down Expand Up @@ -275,14 +275,14 @@ impl< 'a, C: Context, T: Writable< C > > Writable< C > for &'a [T] where [T]: To

#[inline]
fn bytes_needed( &self ) -> Result< usize, C::Error > {
<[T] as Writable::< C >>::bytes_needed( self.as_ref() )
<[T] as Writable::< C >>::bytes_needed( self )
}
}

impl< 'r, C, T > Writable< C > for Cow< 'r, HashSet< T > > where C: Context, T: Writable< C > + Clone + Hash + Eq {
#[inline]
fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > {
(&**self).write_to( writer )
(**self).write_to( writer )
}

#[inline]
Expand All @@ -294,7 +294,7 @@ impl< 'r, C, T > Writable< C > for Cow< 'r, HashSet< T > > where C: Context, T:
impl< 'r, C, T > Writable< C > for Cow< 'r, BTreeSet< T > > where C: Context, T: Writable< C > + Clone + Ord {
#[inline]
fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > {
(&**self).write_to( writer )
(**self).write_to( writer )
}

#[inline]
Expand All @@ -306,7 +306,7 @@ impl< 'r, C, T > Writable< C > for Cow< 'r, BTreeSet< T > > where C: Context, T:
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 {
#[inline]
fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > {
(&**self).write_to( writer )
(**self).write_to( writer )
}

#[inline]
Expand All @@ -318,7 +318,7 @@ impl< 'r, C, K, V > Writable< C > for Cow< 'r, HashMap< K, V > > where C: Contex
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 {
#[inline]
fn write_to< W: ?Sized + Writer< C > >( &self, writer: &mut W ) -> Result< (), C::Error > {
(&**self).write_to( writer )
(**self).write_to( writer )
}

#[inline]
Expand Down Expand Up @@ -671,13 +671,13 @@ impl< C > Writable< C > for Box< str >
{
#[inline]
fn write_to< W >( &self, writer: &mut W ) -> Result< (), C::Error > where W: ?Sized + Writer< C > {
let value: &str = &**self;
let value: &str = self;
value.write_to( writer )
}

#[inline]
fn bytes_needed( &self ) -> Result< usize, C::Error > {
let value: &str = &**self;
let value: &str = self;
Writable::< C >::bytes_needed( value )
}
}
4 changes: 2 additions & 2 deletions src/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,13 @@ pub trait Writer< C: Context > {

#[inline(always)]
fn write_f32( &mut self, value: f32 ) -> Result< (), C::Error > {
let value: u32 = unsafe { mem::transmute( value ) };
let value: u32 = value.to_bits();
self.write_u32( value )
}

#[inline(always)]
fn write_f64( &mut self, value: f64 ) -> Result< (), C::Error > {
let value: u64 = unsafe { mem::transmute( value ) };
let value: u64 = value.to_bits();
self.write_u64( value )
}

Expand Down