From d8525f169649e4ce7e806e68de5e328135755326 Mon Sep 17 00:00:00 2001 From: HampusM Date: Sun, 2 Oct 2022 19:32:25 +0200 Subject: refactor: improve management of feature specific items --- Cargo.toml | 2 ++ macros/Cargo.toml | 2 ++ macros/src/lib.rs | 15 +++++++-------- src/async_di_container.rs | 38 ++++++++++++++------------------------ src/di_container.rs | 10 ++++------ src/errors/async_di_container.rs | 4 ---- src/errors/mod.rs | 4 +++- src/future.rs | 2 -- src/interfaces/async_injectable.rs | 2 -- src/interfaces/mod.rs | 4 +++- src/lib.rs | 18 +++++++++++------- src/ptr.rs | 23 ++++++++++++++++------- 12 files changed, 62 insertions(+), 62 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5e32d16..69be54b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ edition = "2021" [package.metadata.docs.rs] all-features = true +rustdoc-args = ["--cfg", "doc_cfg"] [features] default = ["prevent-circular"] @@ -44,6 +45,7 @@ strum_macros = "0.24.3" paste = "1.0.8" async-trait = { version = "0.1.57", optional = true } tokio = { version = "1.20.1", features = ["sync"], optional = true } +feature_macros = "0.1.0" [dev_dependencies] mockall = "0.11.1" diff --git a/macros/Cargo.toml b/macros/Cargo.toml index e65a4d7..205e9fe 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -13,6 +13,7 @@ proc_macro = true [package.metadata.docs.rs] all-features = true +rustdoc-args = ["--cfg", "doc_cfg"] [features] factory = [] @@ -25,6 +26,7 @@ proc-macro2 = "1.0.40" uuid = { version = "0.8", features = ["v4"] } regex = "1.6.0" once_cell = "1.13.1" +feature_macros = "0.1.0" [dev_dependencies] syrette = { version = "0.4.0", path = "..", features = ["factory"] } diff --git a/macros/src/lib.rs b/macros/src/lib.rs index fc30016..8e906d0 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1,3 +1,5 @@ +#![cfg_attr(doc_cfg, feature(doc_cfg))] +#![feature(proc_macro_hygiene)] #![deny(clippy::all)] #![deny(clippy::pedantic)] #![allow(clippy::module_name_repetitions)] @@ -5,6 +7,7 @@ //! Macros for the [Syrette](https://crates.io/crates/syrette) crate. +use feature_macros::feature_specific; use proc_macro::TokenStream; use quote::quote; use syn::{parse, parse_macro_input}; @@ -15,10 +18,10 @@ mod libs; mod macro_flag; mod util; -#[cfg(feature = "factory")] +#[feature_specific("factory")] mod factory; -#[cfg(feature = "factory")] +#[feature_specific("factory")] mod fn_trait; use crate::declare_interface_args::DeclareInterfaceArgs; @@ -156,8 +159,6 @@ pub fn injectable(args_stream: TokenStream, impl_stream: TokenStream) -> TokenSt /// /// The return type is automatically put inside of a [`TransientPtr`]. /// -/// *This macro is only available if Syrette is built with the "factory" feature.* -/// /// # Arguments /// * (Zero or more) Flags. Like `a = true, b = false` /// @@ -192,8 +193,8 @@ pub fn injectable(args_stream: TokenStream, impl_stream: TokenStream) -> TokenSt /// ``` /// /// [`TransientPtr`]: https://docs.rs/syrette/latest/syrette/ptr/type.TransientPtr.html +#[feature_specific("factory")] #[proc_macro_attribute] -#[cfg(feature = "factory")] pub fn factory(args_stream: TokenStream, type_alias_stream: TokenStream) -> TokenStream { use quote::ToTokens; @@ -267,8 +268,6 @@ pub fn factory(args_stream: TokenStream, type_alias_stream: TokenStream) -> Toke /// Another way to accomplish what this macro does would be by using /// the [`macro@factory`] macro. /// -/// *This macro is only available if Syrette is built with the "factory" feature.* -/// /// # Arguments /// - Interface trait /// * (Zero or more) Flags. Like `a = true, b = false` @@ -292,7 +291,7 @@ pub fn factory(args_stream: TokenStream, type_alias_stream: TokenStream) -> Toke /// declare_default_factory!(dyn IParser); /// ``` #[proc_macro] -#[cfg(feature = "factory")] +#[feature_specific("factory")] pub fn declare_default_factory(args_stream: TokenStream) -> TokenStream { use syn::parse_str; diff --git a/src/async_di_container.rs b/src/async_di_container.rs index f8ce92d..881f64c 100644 --- a/src/async_di_container.rs +++ b/src/async_di_container.rs @@ -50,14 +50,11 @@ //! Ok(()) //! } //! ``` -//! -//! --- -//! -//! *This module is only available if Syrette is built with the "async" feature.* use std::any::type_name; use std::marker::PhantomData; use std::sync::Arc; +use feature_macros::feature_specific; use tokio::sync::Mutex; #[cfg(feature = "factory")] @@ -82,6 +79,7 @@ use crate::provider::r#async::{ use crate::ptr::{SomeThreadsafePtr, ThreadsafeSingletonPtr, TransientPtr}; /// Alias for a threadsafe boxed function. +#[feature_specific("factory")] pub type BoxFn = Box<(dyn Fn + Send + Sync)>; /// When configurator for a binding for type 'Interface' inside a [`AsyncDIContainer`]. @@ -289,11 +287,9 @@ where /// Creates a binding of factory type `Interface` to a factory inside of the /// associated [`AsyncDIContainer`]. /// - /// *This function is only available if Syrette is built with the "factory" feature.* - /// /// # Errors - /// Will return Err if the associated [`AsyncDIContainer`] already have a binding for - /// the interface. + /// Will return Err if the associated [`AsyncDIContainer`] already have a binding + /// for the interface. /// /// # Examples /// ``` @@ -334,7 +330,7 @@ where /// # Ok(()) /// # } /// ``` - #[cfg(feature = "factory")] + #[feature_specific("factory")] pub async fn to_factory( &self, factory_func: &'static FactoryFunc, @@ -373,11 +369,9 @@ where /// Creates a binding of factory type `Interface` to a async factory inside of the /// associated [`AsyncDIContainer`]. /// - /// *This function is only available if Syrette is built with the "factory" feature.* - /// /// # Errors - /// Will return Err if the associated [`AsyncDIContainer`] already have a binding for - /// the interface. + /// Will return Err if the associated [`AsyncDIContainer`] already have a binding + /// for the interface. /// /// # Examples /// ``` @@ -421,7 +415,7 @@ where /// # Ok(()) /// # } /// ``` - #[cfg(all(feature = "factory", feature = "async"))] + #[feature_specific("factory")] pub async fn to_async_factory( &self, factory_func: &'static FactoryFunc, @@ -464,11 +458,9 @@ where /// Creates a binding of type `Interface` to a factory that takes no arguments /// inside of the associated [`AsyncDIContainer`]. /// - /// *This function is only available if Syrette is built with the "factory" feature.* - /// /// # Errors - /// Will return Err if the associated [`AsyncDIContainer`] already have a binding for - /// the interface. + /// Will return Err if the associated [`AsyncDIContainer`] already have a binding + /// for the interface. /// /// # Examples /// ``` @@ -509,7 +501,7 @@ where /// # Ok(()) /// # } /// ``` - #[cfg(feature = "factory")] + #[feature_specific("factory")] pub async fn to_default_factory( &self, factory_func: &'static FactoryFunc, @@ -549,11 +541,9 @@ where /// Creates a binding of factory type `Interface` to a async factory inside of the /// associated [`AsyncDIContainer`]. /// - /// *This function is only available if Syrette is built with the "factory" feature.* - /// /// # Errors - /// Will return Err if the associated [`AsyncDIContainer`] already have a binding for - /// the interface. + /// Will return Err if the associated [`AsyncDIContainer`] already have a binding + /// for the interface. /// /// # Examples /// ``` @@ -597,7 +587,7 @@ where /// # Ok(()) /// # } /// ``` - #[cfg(all(feature = "factory", feature = "async"))] + #[feature_specific("factory")] pub async fn to_async_default_factory( &self, factory_func: &'static FactoryFunc, diff --git a/src/di_container.rs b/src/di_container.rs index 7ccfd3f..7743be8 100644 --- a/src/di_container.rs +++ b/src/di_container.rs @@ -54,6 +54,8 @@ use std::cell::RefCell; use std::marker::PhantomData; use std::rc::Rc; +use feature_macros::feature_specific; + #[cfg(feature = "factory")] use crate::castable_factory::blocking::CastableFactory; use crate::di_container_binding_map::DIContainerBindingMap; @@ -271,8 +273,6 @@ where /// Creates a binding of factory type `Interface` to a factory inside of the /// associated [`DIContainer`]. /// - /// *This function is only available if Syrette is built with the "factory" feature.* - /// /// # Errors /// Will return Err if the associated [`DIContainer`] already have a binding for /// the interface. @@ -333,7 +333,7 @@ where /// # Ok(()) /// # } /// ``` - #[cfg(feature = "factory")] + #[feature_specific("factory")] pub fn to_factory( &self, factory_func: &'static dyn Fn< @@ -375,8 +375,6 @@ where /// Creates a binding of type `Interface` to a factory that takes no arguments /// inside of the associated [`DIContainer`]. /// - /// *This function is only available if Syrette is built with the "factory" feature.* - /// /// # Errors /// Will return Err if the associated [`DIContainer`] already have a binding for /// the interface. @@ -424,7 +422,7 @@ where /// # Ok(()) /// # } /// ``` - #[cfg(feature = "factory")] + #[feature_specific("factory")] pub fn to_default_factory( &self, factory_func: &'static FactoryFunc, diff --git a/src/errors/async_di_container.rs b/src/errors/async_di_container.rs index 22d8fdd..8697bc6 100644 --- a/src/errors/async_di_container.rs +++ b/src/errors/async_di_container.rs @@ -1,9 +1,5 @@ //! Error types for [`AsyncDIContainer`] and it's related structs. //! -//! --- -//! -//! *This module is only available if Syrette is built with the "async" feature.* -//! //! [`AsyncDIContainer`]: crate::async_di_container::AsyncDIContainer use crate::errors::injectable::InjectableError; diff --git a/src/errors/mod.rs b/src/errors/mod.rs index c3930b0..a1eb551 100644 --- a/src/errors/mod.rs +++ b/src/errors/mod.rs @@ -1,8 +1,10 @@ //! Error types for various components of the library. +use feature_macros::feature_specific; + pub mod di_container; pub mod injectable; pub mod ptr; -#[cfg(feature = "async")] +#[feature_specific("async")] pub mod async_di_container; diff --git a/src/future.rs b/src/future.rs index 6df136f..22a6482 100644 --- a/src/future.rs +++ b/src/future.rs @@ -1,6 +1,4 @@ //! Future related utilities. -//! -//! *This module is only available if Syrette is built with the "async" feature.* use std::future::Future; use std::pin::Pin; diff --git a/src/interfaces/async_injectable.rs b/src/interfaces/async_injectable.rs index 07a21aa..69c2a47 100644 --- a/src/interfaces/async_injectable.rs +++ b/src/interfaces/async_injectable.rs @@ -1,6 +1,4 @@ //! Interface for structs that can be injected into or be injected to. -//! -//! *This module is only available if Syrette is built with the "async" feature.* use std::fmt::Debug; use std::sync::Arc; diff --git a/src/interfaces/mod.rs b/src/interfaces/mod.rs index a69da5b..65bac12 100644 --- a/src/interfaces/mod.rs +++ b/src/interfaces/mod.rs @@ -1,5 +1,7 @@ //! Various useful interfaces. +use feature_macros::feature_specific; + pub mod injectable; #[cfg(feature = "factory")] @@ -10,5 +12,5 @@ pub mod any_factory; #[doc(hidden)] pub mod factory; -#[cfg(feature = "async")] +#[feature_specific("async")] pub mod async_injectable; diff --git a/src/lib.rs b/src/lib.rs index b4f43fe..2cd2f03 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,6 @@ #![cfg_attr(feature = "factory", feature(unboxed_closures, fn_traits))] +#![cfg_attr(doc_cfg, feature(doc_cfg))] +#![feature(proc_macro_hygiene)] #![deny(clippy::all)] #![deny(clippy::pedantic)] #![allow(clippy::module_name_repetitions)] @@ -8,21 +10,25 @@ //! //! Syrette is a collection of utilities useful for performing dependency injection. +use feature_macros::feature_specific; + pub mod di_container; pub mod errors; pub mod interfaces; pub mod ptr; -#[cfg(feature = "async")] +#[feature_specific("async")] pub mod async_di_container; -#[cfg(feature = "async")] +#[feature_specific("async")] pub mod future; -#[cfg(feature = "async")] +#[feature_specific("async")] pub use async_di_container::AsyncDIContainer; pub use di_container::DIContainer; -pub use syrette_macros::*; +#[feature_specific("factory")] +pub use syrette_macros::{declare_default_factory, factory}; +pub use syrette_macros::{declare_interface, injectable, named}; #[cfg(feature = "factory")] #[doc(hidden)] @@ -82,8 +88,6 @@ macro_rules! di_container_bind { /// Creates a async closure. /// -/// *This macro is only available if Syrette is built with the "async" feature.* -/// /// # Examples /// ``` /// # use syrette::async_closure; @@ -118,7 +122,7 @@ macro_rules! di_container_bind { /// }) /// }); /// ``` -#[cfg(feature = "async")] +#[feature_specific("async")] #[macro_export] macro_rules! async_closure { (|$($args: ident),*| { $($inner: stmt);* }) => { diff --git a/src/ptr.rs b/src/ptr.rs index 426a796..824b086 100644 --- a/src/ptr.rs +++ b/src/ptr.rs @@ -2,6 +2,7 @@ use std::rc::Rc; use std::sync::Arc; +use feature_macros::feature_specific; use paste::paste; use crate::errors::ptr::{SomePtrError, SomeThreadsafePtrError}; @@ -16,15 +17,19 @@ pub type SingletonPtr = Rc; pub type ThreadsafeSingletonPtr = Arc; /// A smart pointer to a factory. -#[cfg(feature = "factory")] +#[feature_specific("factory")] pub type FactoryPtr = Rc; /// A threadsafe smart pointer to a factory. -#[cfg(feature = "factory")] +#[feature_specific("factory")] pub type ThreadsafeFactoryPtr = Arc; macro_rules! create_as_variant_fn { ($enum: ident, $variant: ident) => { + create_as_variant_fn!($enum, $variant,); + }; + + ($enum: ident, $variant: ident, $($attrs: meta),*) => { paste! { #[doc = "Returns as the `" [<$variant>] "` variant.\n" @@ -32,13 +37,13 @@ macro_rules! create_as_variant_fn { "# Errors\n" "Will return Err if it's not the `" [<$variant>] "` variant." ] + $(#[$attrs]),* pub fn [<$variant:snake>](self) -> Result<[<$variant Ptr>], [<$enum Error>]> { if let $enum::$variant(ptr) = self { return Ok(ptr); } - Err([<$enum Error>]::WrongPtrType { expected: stringify!($variant), found: self.into() @@ -62,6 +67,7 @@ where /// A smart pointer to a factory. #[cfg(feature = "factory")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))] Factory(FactoryPtr), } @@ -73,8 +79,7 @@ where create_as_variant_fn!(SomePtr, Singleton); - #[cfg(feature = "factory")] - create_as_variant_fn!(SomePtr, Factory); + create_as_variant_fn!(SomePtr, Factory, feature_specific("factory")); } /// Some threadsafe smart pointer. @@ -91,6 +96,7 @@ where /// A smart pointer to a factory. #[cfg(feature = "factory")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))] ThreadsafeFactory(ThreadsafeFactoryPtr), } @@ -102,6 +108,9 @@ where create_as_variant_fn!(SomeThreadsafePtr, ThreadsafeSingleton); - #[cfg(feature = "factory")] - create_as_variant_fn!(SomeThreadsafePtr, ThreadsafeFactory); + create_as_variant_fn!( + SomeThreadsafePtr, + ThreadsafeFactory, + feature_specific("factory") + ); } -- cgit v1.2.3-18-g5258