diff --git a/Cargo.toml b/Cargo.toml index 7c2f62d..dc529f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,5 +12,13 @@ repository = "https://github.com/TimelyDataflow/abomonation.git" keywords = ["abomonation"] license = "MIT" +[dependencies] +core2 = { version = "0.3", default-features = false, features = [ "alloc" ] } +smoltcp = { version = "0.7.1", default-features = false, features = [ "alloc", "log", "proto-ipv4", "proto-ipv6", "proto-igmp", "proto-dhcpv4", "socket-raw", "socket-icmp", "socket-udp", "socket-tcp" ] } + [dev-dependencies] recycler="0.1.4" + +[features] +default = ["std"] +std = [] diff --git a/benches/serde.rs b/benches/serde.rs index 5965794..4aad85a 100644 --- a/benches/serde.rs +++ b/benches/serde.rs @@ -3,9 +3,24 @@ extern crate abomonation; extern crate test; +#[cfg(not(feature="std"))] +extern crate core2; + use test::Bencher; use abomonation::{Abomonation, encode, decode}; +#[cfg(feature="std")] +use { + std::io::Write, + std::io::Result as IOResult, +}; + +#[cfg(not(feature="std"))] +use { + core2::io::Write, + core2::io::Result as IOResult, +}; + #[bench] fn bench_populate(b: &mut Bencher) { b.iter(|| { diff --git a/src/abomonated.rs b/src/abomonated.rs index 328b195..31e3b62 100644 --- a/src/abomonated.rs +++ b/src/abomonated.rs @@ -1,7 +1,18 @@ +#![cfg_attr(not(feature = "std"), no_std)] -use std::mem::transmute; -use std::marker::PhantomData; -use std::ops::{Deref, DerefMut}; +#[cfg(feature="std")] +use { + std::mem::transmute, + std::marker::PhantomData, + std::ops::{Deref, DerefMut}, +}; + +#[cfg(not(feature="std"))] +use { + core::mem::transmute, + core::marker::PhantomData, + core::ops::{Deref, DerefMut}, +}; use super::{Abomonation, decode}; diff --git a/src/lib.rs b/src/lib.rs index 016bcc8..aab4703 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,12 +34,47 @@ //! assert!(remaining.len() == 0); //! } //! ``` - -use std::mem; // yup, used pretty much everywhere. -use std::io::Write; // for bytes.write_all; push_all is unstable and extend is slow. -use std::io::Result as IOResult; -use std::marker::PhantomData; -use std::num::*; +#![cfg_attr(not(feature="std"), no_std)] + +#[cfg(not(feature="std"))] +extern crate core2; + +#[cfg(not(feature="std"))] +extern crate smoltcp; + +#[cfg(not(feature="std"))] +extern crate alloc; + +#[cfg(feature="std")] +use { + std::mem as mem, // yup, used pretty much everywhere. + std::io::Write, // for bytes.write_all; push_all is unstable and extend is slow. + std::io::Result as IOResult, + std::marker::PhantomData, + std::num::*, + std::slice as slice, + std::time::Duration, + std::ops::Range, + std::ptr::write as ptr_write, +}; + +#[cfg(not(feature="std"))] +use { + core::mem as mem, + core::marker::PhantomData, + core::num::*, + core::slice as slice, + core::time::Duration, + core::ops::Range, + core::ptr::write as ptr_write, + + core2::io::Write, + core2::io::Result as IOResult, + + alloc::vec::Vec, + alloc::boxed::Box, + alloc::string::String, +}; pub mod abomonated; @@ -72,7 +107,7 @@ pub mod abomonated; /// #[inline] pub unsafe fn encode(typed: &T, write: &mut W) -> IOResult<()> { - let slice = std::slice::from_raw_parts(mem::transmute(typed), mem::size_of::()); + let slice = slice::from_raw_parts(mem::transmute(typed), mem::size_of::()); write.write_all(slice)?; typed.entomb(write)?; Ok(()) @@ -216,14 +251,13 @@ pub trait Abomonation { /// } /// ``` #[macro_export] -#[deprecated(since="0.5", note="please use the abomonation_derive crate")] macro_rules! unsafe_abomonate { ($t:ty) => { impl Abomonation for $t { } }; ($t:ty : $($field:ident),*) => { impl Abomonation for $t { - #[inline] unsafe fn entomb(&self, write: &mut W) -> ::std::io::Result<()> { + #[inline] unsafe fn entomb(&self, write: &mut W) -> IOResult<()> { $( self.$field.entomb(write)?; )* Ok(()) } @@ -303,11 +337,11 @@ impl Abomonation for () { } impl Abomonation for char { } -impl Abomonation for ::std::time::Duration { } +impl Abomonation for Duration { } impl Abomonation for PhantomData {} -impl Abomonation for std::ops::Range { +impl Abomonation for Range { #[inline(always)] unsafe fn entomb(&self, write: &mut W) -> IOResult<()> { self.start.entomb(write)?; self.end.entomb(write)?; @@ -401,7 +435,7 @@ macro_rules! array_abomonate { ($size:expr) => ( impl Abomonation for [T; $size] { #[inline(always)] - unsafe fn entomb(&self, write: &mut W) -> IOResult<()> { + unsafe fn entomb(&self, write: &mut W) -> IOResult<()> { for element in self { element.entomb(write)?; } Ok(()) } @@ -468,7 +502,7 @@ impl Abomonation for String { if self.len() > bytes.len() { None } else { let (mine, rest) = bytes.split_at_mut(self.len()); - std::ptr::write(self, String::from_raw_parts(mem::transmute(mine.as_ptr()), self.len(), self.len())); + ptr_write(self, String::from_raw_parts(mem::transmute(mine.as_ptr()), self.len(), self.len())); Some(rest) } } @@ -492,8 +526,8 @@ impl Abomonation for Vec { if binary_len > bytes.len() { None } else { let (mine, mut rest) = bytes.split_at_mut(binary_len); - let slice = std::slice::from_raw_parts_mut(mine.as_mut_ptr() as *mut T, self.len()); - std::ptr::write(self, Vec::from_raw_parts(slice.as_mut_ptr(), self.len(), self.len())); + let slice = slice::from_raw_parts_mut(mine.as_mut_ptr() as *mut T, self.len()); + ptr_write(self, Vec::from_raw_parts(slice.as_mut_ptr(), self.len(), self.len())); for element in self.iter_mut() { let temp = rest; // temp variable explains lifetimes (mysterious!) rest = element.exhume(temp)?; @@ -514,7 +548,7 @@ impl Abomonation for Vec { impl Abomonation for Box { #[inline] unsafe fn entomb(&self, bytes: &mut W) -> IOResult<()> { - bytes.write_all(std::slice::from_raw_parts(mem::transmute(&**self), mem::size_of::()))?; + bytes.write_all(slice::from_raw_parts(mem::transmute(&**self), mem::size_of::()))?; (**self).entomb(bytes)?; Ok(()) } @@ -524,7 +558,7 @@ impl Abomonation for Box { if binary_len > bytes.len() { None } else { let (mine, mut rest) = bytes.split_at_mut(binary_len); - std::ptr::write(self, mem::transmute(mine.as_mut_ptr() as *mut T)); + ptr_write(self, mem::transmute(mine.as_mut_ptr() as *mut T)); let temp = rest; rest = (**self).exhume(temp)?; Some(rest) } @@ -536,18 +570,28 @@ impl Abomonation for Box { // This method currently enables undefined behavior, by exposing padding bytes. #[inline] unsafe fn typed_to_bytes(slice: &[T]) -> &[u8] { - std::slice::from_raw_parts(slice.as_ptr() as *const u8, slice.len() * mem::size_of::()) + slice::from_raw_parts(slice.as_ptr() as *const u8, slice.len() * mem::size_of::()) } mod network { use Abomonation; + + #[cfg(feature="std")] use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6, IpAddr, Ipv4Addr, Ipv6Addr}; + #[cfg(not(feature="std"))] + use smoltcp::wire::{IpAddress as IpAddr, Ipv4Address as Ipv4Addr, Ipv6Address as Ipv6Addr}; + impl Abomonation for IpAddr { } impl Abomonation for Ipv4Addr { } impl Abomonation for Ipv6Addr { } + #[cfg(feature="std")] impl Abomonation for SocketAddr { } + + #[cfg(feature="std")] impl Abomonation for SocketAddrV4 { } + + #[cfg(feature="std")] impl Abomonation for SocketAddrV6 { } }