Skip to content

Commit

Permalink
Make ouroboros no_std compatible.
Browse files Browse the repository at this point in the history
* Mark the crate `#![no_std]`.
* Replace all references to `std` with `core` or `alloc`.
* Don't mention `Arc` if the target doesn't support it.
* Reexport `alloc` from `ouroboros::macro_help` so that the crate
  calling the macro doesn't need any `extern crate alloc`.
  • Loading branch information
kpreid committed Jun 18, 2022
1 parent d8653d1 commit b4537fd
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 10 deletions.
12 changes: 8 additions & 4 deletions ouroboros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! See the documentation of [`ouroboros_examples`](https://docs.rs/ouroboros_examples) for
//! sample documentation of structs which have had the macro applied to them.
#![no_std]
#![allow(clippy::needless_doctest_main)]

/// This macro is used to turn a regular struct into a self-referencing one. An example:
Expand Down Expand Up @@ -348,10 +349,12 @@ pub use ouroboros_macro::self_referencing;

#[doc(hidden)]
pub mod macro_help {
pub extern crate alloc;

pub use aliasable::boxed::AliasableBox;
use aliasable::boxed::UniqueBox;

pub struct CheckIfTypeIsStd<T>(std::marker::PhantomData<T>);
pub struct CheckIfTypeIsStd<T>(core::marker::PhantomData<T>);

macro_rules! std_type_check {
($fn_name:ident $T:ident $check_for:ty) => {
Expand All @@ -361,9 +364,10 @@ pub mod macro_help {
};
}

std_type_check!(is_std_box_type T std::boxed::Box<T>);
std_type_check!(is_std_arc_type T std::sync::Arc<T>);
std_type_check!(is_std_rc_type T std::rc::Rc<T>);
std_type_check!(is_std_box_type T alloc::boxed::Box<T>);
#[cfg(target_has_atomic = "ptr")] // alloc::sync is missing if this is false
std_type_check!(is_std_arc_type T alloc::sync::Arc<T>);
std_type_check!(is_std_rc_type T alloc::rc::Rc<T>);

pub fn aliasable_boxed<T>(data: T) -> AliasableBox<T> {
AliasableBox::from_unique(UniqueBox::new(data))
Expand Down
4 changes: 2 additions & 2 deletions ouroboros_macro/src/generate/derives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ fn impl_debug(info: &StructInfo) -> Result<TokenStream, Error> {
}
})
.collect::<Vec<_>>();
let trait_name = syn::parse_quote! { ::std::fmt::Debug };
let trait_name = syn::parse_quote! { ::core::fmt::Debug };
let struct_name = &info.ident;
let body = quote! {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
self.with(|safe_self| {
f.debug_struct(stringify!(#struct_name))
#(.#fields)*
Expand Down
20 changes: 16 additions & 4 deletions ouroboros_macro/src/info_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,14 @@ impl StructFieldInfo {
let field_type = &self.typ;
let return_ty_constructor = || match builder_type {
BuilderType::AsyncSend => {
quote! { ::std::pin::Pin<::std::boxed::Box<dyn ::core::future::Future<Output=#field_type> + ::core::marker::Send + 'this>> }
quote! {
::core::pin::Pin<::ouroboros::macro_help::alloc::boxed::Box<
dyn ::core::future::Future<Output=#field_type> + ::core::marker::Send + 'this>>
}
}
BuilderType::Async => {
quote! { ::std::pin::Pin<::std::boxed::Box<dyn ::core::future::Future<Output=#field_type> + 'this>> }
quote! { ::core::pin::Pin<::ouroboros::macro_help::alloc::boxed::Box<
dyn ::core::future::Future<Output=#field_type> + 'this>> }
}
BuilderType::Sync => quote! { #field_type },
};
Expand All @@ -280,10 +284,18 @@ impl StructFieldInfo {
let field_type = &self.typ;
let return_ty_constructor = || match builder_type {
BuilderType::AsyncSend => {
quote! { ::std::pin::Pin<::std::boxed::Box<dyn ::core::future::Future<Output=::core::result::Result<#field_type, Error_>> + ::core::marker::Send + 'this>> }
quote! {
::core::pin::Pin<::ouroboros::macro_help::alloc::boxed::Box<
dyn ::core::future::Future<Output=::core::result::Result<#field_type, Error_>>
+ ::core::marker::Send + 'this>>
}
}
BuilderType::Async => {
quote! { ::std::pin::Pin<::std::boxed::Box<dyn ::core::future::Future<Output=::core::result::Result<#field_type, Error_>> + 'this>> }
quote! {
::core::pin::Pin<::ouroboros::macro_help::alloc::boxed::Box<
dyn ::core::future::Future<Output=::core::result::Result<#field_type, Error_>>
+ 'this>>
}
}
BuilderType::Sync => quote! { ::core::result::Result<#field_type, Error_> },
};
Expand Down

0 comments on commit b4537fd

Please sign in to comment.