Skip to content

Commit

Permalink
allow no-std but alloc (#13)
Browse files Browse the repository at this point in the history
There were a few types which implement `LifetimeFree` only in `std` mode. This PR lowers the requirement by introducing a new `alloc` feature that enables these traits in `no-std` mode but when `alloc` is still available. These types include `String`, `Box`, `Vec`, and `Arc`, which has an additional (automatic) cfg due to only existing on platforms with ptr-sized atomics.
  • Loading branch information
dragazo authored Sep 29, 2023
1 parent 437fbda commit 564b11f
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 13 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ all-features = true

[features]
default = ["std"]
std = []
std = ["alloc"]
alloc = []

[dependencies]
rustversion = "1"
Expand Down
23 changes: 18 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
//! This crate works fully on stable Rust, and also does not require the
//! standard library. To disable references to the standard library, you must
//! opt-out of the `std` feature using `default-features = false` in your
//! `Cargo.toml` file.
//! `Cargo.toml` file. When in no-std mode, a separate `alloc` feature flag
//! is available to support casting to several [`alloc`] types not included
//! in [`core`].
//!
//! Castaway provides the following key macros:
//!
Expand All @@ -12,7 +14,13 @@
//! - [`match_type`]: Match the result of an expression against multiple
//! concrete types.

#![cfg_attr(not(feature = "std"), no_std)]
#![no_std]

#[cfg(feature = "std")]
extern crate std;

#[cfg(feature = "alloc")]
extern crate alloc;

#[doc(hidden)]
pub mod internal;
Expand Down Expand Up @@ -79,8 +87,10 @@ pub use lifetime_free::LifetimeFree;
/// `'static`. To mark a type as being lifetime-free and enable it to be casted
/// to in this manner by this macro it must implement the [`LifetimeFree`]
/// trait. This is implemented automatically for all primitive types and for
/// several `core` types. If you enable the `std` crate feature, then it will
/// also be implemented for several `std` types as well.
/// several [`core`] types. If you enable the `std` crate feature, then it will
/// also be implemented for several [`std`] types as well. If you enable the
/// `alloc` crate feature, then it will be implemented for several [`alloc`]
/// types without linking to the standard library as the `std` feature would.
///
/// # Examples
///
Expand Down Expand Up @@ -278,6 +288,9 @@ macro_rules! match_type {
mod tests {
use super::*;

#[cfg(feature = "alloc")]
use alloc::string::String;

#[test]
fn cast() {
assert_eq!(cast!(0u8, u16), Err(0u8));
Expand Down Expand Up @@ -489,7 +502,7 @@ mod tests {
3.2f64 => Err(v) if v == 3.2f64,
}

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
for String {
String::from("hello world") => Ok(ref v) if v.as_str() == "hello world",
"hello world" => Err("hello world"),
Expand Down
16 changes: 9 additions & 7 deletions src/lifetime_free.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/// types are safe to cast from non-static type parameters if their types are
/// equal.
///
/// This trait is used by [`cast!`] to determine what casts are legal on values
/// This trait is used by [`cast!`](crate::cast) to determine what casts are legal on values
/// without a `'static` type constraint.
///
/// # Safety
Expand Down Expand Up @@ -104,13 +104,15 @@ tuple_impls! {
T0 T1 T2 T3 T4 T5 T6 T7 T8 T9,
}

#[cfg(feature = "std")]
mod std_impls {
#[cfg(feature = "alloc")]
mod alloc_impls {
use super::LifetimeFree;

unsafe impl LifetimeFree for String {}
unsafe impl LifetimeFree for alloc::string::String {}

unsafe impl<T: LifetimeFree> LifetimeFree for Box<T> {}
unsafe impl<T: LifetimeFree> LifetimeFree for Vec<T> {}
unsafe impl<T: LifetimeFree> LifetimeFree for std::sync::Arc<T> {}
unsafe impl<T: LifetimeFree> LifetimeFree for alloc::boxed::Box<T> {}
unsafe impl<T: LifetimeFree> LifetimeFree for alloc::vec::Vec<T> {}

#[rustversion::attr(since(1.60), cfg(target_has_atomic = "ptr"))]
unsafe impl<T: LifetimeFree> LifetimeFree for alloc::sync::Arc<T> {}
}

0 comments on commit 564b11f

Please sign in to comment.