Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace all std with alloc except for std::error::Error #59

Merged
merged 6 commits into from
Jul 8, 2019
Merged
Show file tree
Hide file tree
Changes from 3 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
5 changes: 4 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ matrix:
- env: LANGUAGE=Rust MIRI=true
language: rust
rust: nightly
- env: LANGUAGE=Rust CARGO_DEFAULT_FEATURES=--no-default-features
- env: LANGUAGE=Rust CARGO_DEFAULT_FEATURES="--no-default-features"
language: rust
rust: stable
- env: LANGUAGE=Rust CARGO_DEFAULT_FEATURES="--no-default-features --features alloc"
language: rust
rust: stable
allow_failures:
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ exclude = ["*.enc"]

[features]
default = ["std"]
"std" = []
"std" = ["alloc"]
"alloc" = []
4 changes: 2 additions & 2 deletions src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use self::super::guard::{SingleValueGuard, PermissiveGuard, SingleManyGuard, Guard};
use self::super::error::Error;
use core::mem::size_of;
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
use core::mem::forget;
use core::slice;

Expand Down Expand Up @@ -253,7 +253,7 @@ pub unsafe fn transmute_many_permissive<T>(bytes: &[u8]) -> &[T] {
/// );
/// }
/// ```
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub unsafe fn transmute_vec<S, T>(mut vec: Vec<S>) -> Vec<T> {
let ptr = vec.as_mut_ptr();
let capacity = vec.capacity() * size_of::<S>() / size_of::<T>();
Expand Down
6 changes: 3 additions & 3 deletions src/bool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

use self::super::guard::{PermissiveGuard, PedanticGuard, Guard};
use self::super::base::transmute_many;
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
use self::super::base::transmute_vec;
use core::mem::transmute;
use self::super::Error;
Expand Down Expand Up @@ -117,7 +117,7 @@ pub fn transmute_bool_pedantic(bytes: &[u8]) -> Result<&[bool], Error<u8, bool>>
/// # }
/// # run().unwrap()
/// ```
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub fn transmute_bool_vec_permissive(bytes: Vec<u8>) -> Result<Vec<bool>, Error<'static, u8, bool>> {
check_bool(&bytes)?;
PermissiveGuard::check::<u8>(&bytes)?;
Expand Down Expand Up @@ -146,7 +146,7 @@ pub fn transmute_bool_vec_permissive(bytes: Vec<u8>) -> Result<Vec<bool>, Error<
/// # }
/// # run().unwrap()
/// ```
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub fn transmute_bool_vec_pedantic(bytes: Vec<u8>) -> Result<Vec<bool>, Error<'static, u8, bool>> {
check_bool(&bytes)?;
PedanticGuard::check::<u8>(&bytes)?;
Expand Down
36 changes: 18 additions & 18 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@


use core::fmt;
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
use core::ptr;
use core::marker::PhantomData;
#[cfg(feature = "std")]
use std::error::Error as StdError;
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
use core::mem::{align_of, size_of};
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
use self::super::trivial::TriviallyTransmutable;


Expand All @@ -32,8 +32,8 @@ pub enum Error<'a, S, T> {
/// The data vector's element type does not have the same size and minimum
/// alignment as the target type.
///
/// Does not exist in `no_std`.
#[cfg(feature = "std")]
/// Does not exist without the `alloc` feature.
#[cfg(feature = "alloc")]
IncompatibleVecTarget(IncompatibleVecTargetError<S, T>),
/// The data contains an invalid value for the target type.
InvalidValue,
Expand All @@ -44,7 +44,7 @@ impl<'a, S, T> Error<'a, S, T> {
/// an unaligned memory access, or an incompatible vector element target.
///
/// Otherwise return `self`.
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub fn copy(self) -> Result<Vec<T>, Error<'a, S, T>>
where T: TriviallyTransmutable
{
Expand All @@ -64,7 +64,7 @@ impl<'a, S, T> Error<'a, S, T> {
///
/// The source data needs to correspond to a valid contiguous sequence of
/// `T` values.
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub unsafe fn copy_unchecked(self) -> Result<Vec<T>, Error<'a, S, T>> {
match self {
Error::Unaligned(e) => Ok(e.copy_unchecked()),
Expand All @@ -87,7 +87,7 @@ impl<'a, S, T> Error<'a, S, T> {
}
Error::Guard(e) => Error::Guard(e),
Error::InvalidValue => Error::InvalidValue,
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
Error::IncompatibleVecTarget(e) => Error::IncompatibleVecTarget(e),
}
}
Expand All @@ -99,7 +99,7 @@ impl<'a, S, T> fmt::Debug for Error<'a, S, T> {
Error::Guard(e) => write!(f, "Guard({:?})", e),
Error::Unaligned(e) => write!(f, "Unaligned({:?})", e),
Error::InvalidValue => f.write_str("InvalidValue"),
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
Error::IncompatibleVecTarget(_) => f.write_str("IncompatibleVecTarget"),
}
}
Expand All @@ -123,7 +123,7 @@ impl<'a, S, T> fmt::Display for Error<'a, S, T> {
Error::Guard(e) => e.fmt(f),
Error::Unaligned(e) => e.fmt(f),
Error::InvalidValue => f.write_str("Invalid target value"),
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
Error::IncompatibleVecTarget(e) => e.fmt(f),
}
}
Expand Down Expand Up @@ -215,7 +215,7 @@ impl ErrorReason {
///
/// The byte data in the vector needs to correspond to a valid contiguous
/// sequence of `T` values.
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
unsafe fn copy_to_vec_unchecked<S, T>(data: &[S]) -> Vec<T> {
let len = data.len() * size_of::<S>() / size_of::<T>();

Expand Down Expand Up @@ -259,7 +259,7 @@ impl<'a, S, T> UnalignedError<'a, S, T> {
///
/// The byte data in the slice needs to correspond to a valid contiguous
/// sequence of `T` values.
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub unsafe fn copy_unchecked(&self) -> Vec<T> {
copy_to_vec_unchecked::<S, T>(self.source)
}
Expand All @@ -268,7 +268,7 @@ impl<'a, S, T> UnalignedError<'a, S, T> {
/// trivially transmutable, and the vector will be properly allocated
/// for accessing values of type `T`, this operation is safe and will never
/// fail.
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub fn copy(&self) -> Vec<T>
where T: TriviallyTransmutable
{
Expand Down Expand Up @@ -324,7 +324,7 @@ impl<'a, S, T> fmt::Display for UnalignedError<'a, S, T> {
///
/// - `std::mem::align_of::<S>() != std::mem::align_of::<T>()`
/// - `std::mem::size_of::<S>() != std::mem::size_of::<T>()`
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
#[derive(Clone, Eq, Hash, PartialEq)]
pub struct IncompatibleVecTargetError<S, T> {
/// The original vector.
Expand All @@ -333,7 +333,7 @@ pub struct IncompatibleVecTargetError<S, T> {
target: PhantomData<T>,
}

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
impl<S, T> IncompatibleVecTargetError<S, T> {
/// Create an error with the given vector.
pub fn new(vec: Vec<S>) -> Self {
Expand Down Expand Up @@ -368,14 +368,14 @@ impl<S, T> IncompatibleVecTargetError<S, T> {
}
}

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
impl<'a, S, T> From<IncompatibleVecTargetError<S, T>> for Error<'a, S, T> {
fn from(e: IncompatibleVecTargetError<S, T>) -> Self {
Error::IncompatibleVecTarget(e)
}
}

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
impl<S, T> fmt::Debug for IncompatibleVecTargetError<S, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("IncompatibleVecTargetError")
Expand All @@ -394,7 +394,7 @@ impl<S, T> StdError for IncompatibleVecTargetError<S, T> {
}
}

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
impl<S, T> fmt::Display for IncompatibleVecTargetError<S, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f,
Expand Down
8 changes: 4 additions & 4 deletions src/full.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@

use self::super::trivial::{TriviallyTransmutable, transmute_trivial, transmute_trivial_many, transmute_trivial_many_mut};
use self::super::guard::{SingleValueGuard, PermissiveGuard, PedanticGuard, Guard};
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
use self::super::error::IncompatibleVecTargetError;
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
use core::mem::{align_of, size_of, forget};
use self::super::align::{check_alignment, check_alignment_mut};
use self::super::Error;
Expand Down Expand Up @@ -258,7 +258,7 @@ pub fn transmute_many_pedantic_mut<T: TriviallyTransmutable>(bytes: &mut [u8]) -
///
/// ```
/// # use safe_transmute::transmute_vec;
/// # fn run() -> Result<(), Box<::std::error::Error>> {
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// assert_eq!(transmute_vec::<u8, i8>(vec![0x00, 0x01, 0x00, 0x02])?,
/// vec![0x00i8, 0x01i8, 0x00i8, 0x02i8]);
/// assert_eq!(transmute_vec::<u8, i8>(vec![0x04, 0x00, 0x00, 0x00, 0xED])?,
Expand All @@ -267,7 +267,7 @@ pub fn transmute_many_pedantic_mut<T: TriviallyTransmutable>(bytes: &mut [u8]) -
/// # }
/// # run().unwrap();
/// ```
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub fn transmute_vec<S: TriviallyTransmutable, T: TriviallyTransmutable>(mut vec: Vec<S>) -> Result<Vec<T>, Error<'static, S, T>> {
if align_of::<S>() != align_of::<T>() || size_of::<S>() != size_of::<T>() {
return Err(IncompatibleVecTargetError::new(vec).into());
Expand Down
23 changes: 15 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
//!
//! This crate can be used in a no-`std` environment by disabling the `std`
//! feature through specifying `default-features = false` on import.
//! However, `std` is only used for integration with `std::error::Error`.
//!
//! Note, though, that funxions operating on items from `alloc` will also be disabled by this.
//! If your no-`std` environment has an `alloc` implementation, you will have to reenable them by using `features = ["alloc"]`.
//!
//! # Migrating
//!
Expand All @@ -46,7 +50,7 @@
//! ```
//! # use safe_transmute::{SingleManyGuard, Error, transmute_many};
//! # #[cfg(feature = "std")]
//! # fn main() -> Result<(), Box<::std::error::Error>> {
//! # fn main() -> Result<(), Box<std::error::Error>> {
//! let bytes = &[0x00, 0x01, 0x12, 0x24,
//! 0x00]; // 1 spare byte
//! match transmute_many::<u16, SingleManyGuard>(bytes) {
Expand Down Expand Up @@ -80,7 +84,7 @@
//! # extern crate safe_transmute;
//! # use safe_transmute::{SingleManyGuard, Error, transmute_many};
//! # #[cfg(feature = "std")]
//! # fn main() -> Result<(), Box<::std::error::Error>> {
//! # fn main() -> Result<(), Box<std::error::Error>> {
//! let bytes = &[0x00, 0x01, 0x12, 0x24, 0x00];
//! let words = try_copy!(transmute_many::<u16, SingleManyGuard>(bytes));
//!
Expand All @@ -100,7 +104,7 @@
//! # use safe_transmute::{Error, transmute_many_pedantic};
//! # include!("../tests/test_util/le_to_native.rs");
//! # #[cfg(feature = "std")]
//! # fn main() -> Result<(), Box<::std::error::Error>> {
//! # fn main() -> Result<(), Box<std::error::Error>> {
//! # let bytes = &[0x00, 0x01, 0x12, 0x34].le_to_native::<u16>();
//! # let words = try_copy!(transmute_many_pedantic::<u16>(bytes).map_err(Error::without_src));
//! # /*
Expand Down Expand Up @@ -151,8 +155,11 @@
#![cfg_attr(not(feature = "std"), no_std)]


#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
extern crate core;
#[cfg(feature = "alloc")]
#[doc(hidden)]
pub extern crate alloc;

mod full;

Expand All @@ -168,20 +175,20 @@ pub mod migration;

pub use self::full::{transmute_many_permissive_mut, transmute_many_pedantic_mut, transmute_many_permissive, transmute_many_pedantic, transmute_one_pedantic,
transmute_many, transmute_many_mut, transmute_one};
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub use self::full::transmute_vec;


pub use self::guard::{SingleValueGuard, PermissiveGuard, SingleManyGuard, PedanticGuard, Guard};
pub use self::error::{UnalignedError, ErrorReason, GuardError, Error};
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub use self::error::IncompatibleVecTargetError;
pub use self::trivial::{TriviallyTransmutable, align_to_mut, align_to};

pub use self::to_bytes::{transmute_one_to_bytes_mut, transmute_one_to_bytes, transmute_to_bytes_mut, transmute_to_bytes};
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub use self::to_bytes::transmute_to_bytes_vec;

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub use self::bool::{transmute_bool_vec_permissive, transmute_bool_vec_pedantic};
pub use self::bool::{transmute_bool_permissive, transmute_bool_pedantic};
10 changes: 5 additions & 5 deletions src/migration/v0_11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
//! `transmute_many_permissive()`.
//!
//! ```rust
//! # #[cfg(feature = "std")]
//! # #[cfg(feature = "alloc")]
//! # {
//! use safe_transmute::{Error, transmute_many_permissive};
//!
Expand Down Expand Up @@ -81,7 +81,7 @@
//!
//! ```rust
//! # use safe_transmute::Error;
//! # #[cfg(feature = "std")]
//! # #[cfg(feature = "alloc")]
//! # {
//! use safe_transmute::{transmute_many_permissive, try_copy};
//!
Expand All @@ -101,12 +101,12 @@
//!
//! You might have used safe-transmute's vector transmutation functions. Well, it turns out that they are
//! **incredibly unsafe**, and hard to get it right. This will be more complicated to migrate efficiently.
//! The new `transmute_vec()` only works under very restricted conditions: the `mem::align_of()` and `mem::size_of()` between the
//! source and target element types must match. Otherwise, a full copy of the vector must be made.
//! The new `transmute_vec()` only works under very restricted conditions: the `mem::align_of()` and `mem::size_of()` between
//! the source and target element types must match. Otherwise, a full copy of the vector must be made.
//!
//! ```rust
//! # use safe_transmute::Error;
//! # #[cfg(feature = "std")]
//! # #[cfg(feature = "alloc")]
//! # {
//! use safe_transmute::{transmute_vec, try_copy};
//!
Expand Down
4 changes: 2 additions & 2 deletions src/to_bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


use self::super::TriviallyTransmutable;
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
use self::super::Error;
use core::mem::size_of;
use core::slice;
Expand Down Expand Up @@ -431,7 +431,7 @@ pub fn guarded_transmute_to_bytes_pod_many<S: TriviallyTransmutable>(from: &[S])
/// The only truly safe way of doing this is to create a transmuted slice
/// view of the vector or make a copy anyway.
///
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub fn transmute_to_bytes_vec<S: TriviallyTransmutable>(from: Vec<S>) -> Result<Vec<u8>, Error<'static, S, u8>> {
super::full::transmute_vec::<S, u8>(from)
}
4 changes: 2 additions & 2 deletions src/trivial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

use self::super::guard::{PermissiveGuard, PedanticGuard, Guard};
use self::super::base::{transmute_many, transmute_many_mut, from_bytes};
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
use self::super::base::transmute_vec;
use self::super::Error;

Expand Down Expand Up @@ -345,7 +345,7 @@ pub unsafe fn guarded_transmute_pod_many_pedantic<T: TriviallyTransmutable>(byte
/// );
/// }
/// ```
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
pub unsafe fn transmute_trivial_vec<S: TriviallyTransmutable, T: TriviallyTransmutable>(vec: Vec<S>) -> Vec<T> {
transmute_vec::<S, T>(vec)
}
Loading