From 808bc022f34d057b324c5e8f6e6d291a20180cfa Mon Sep 17 00:00:00 2001 From: Richard Bradfield Date: Tue, 2 Jun 2020 12:17:59 +0100 Subject: [PATCH] Cargo Format --- src/context.rs | 42 +++++++++++++++++++++--------------------- src/interface.rs | 22 +++++++++++----------- src/lib.rs | 47 +++++++++++++++++++++++------------------------ src/main.rs | 8 +++++--- 4 files changed, 60 insertions(+), 59 deletions(-) diff --git a/src/context.rs b/src/context.rs index 734cde9..a4e963a 100644 --- a/src/context.rs +++ b/src/context.rs @@ -177,43 +177,43 @@ macro_rules! private_define_context { /// Define a new context. Typically used at the top level of an /// application to contain the full set of requried dependencies. -/// +/// /// Contexts follow a struct-like syntax, although the names of /// fields are for the most part unimportant. -/// +/// /// Contexts automatically implement all applicable interfaces. /// An interface is applicable if all of the dependencies /// required by that interface are present in the context. -/// +/// /// Dependencies are identified by *type*, not by the field name. /// Contexts may not contain two fields of the same type. Instead /// use new-type wrappers to distinguish similar dependencies. -/// +/// /// Types used in a context must implement `Clone + Debug`, and /// `Clone` should be a cheap operation. For this reason it is usual /// to wrap dependencies in an `Rc` or `Arc`. -/// +/// /// A constructor function will be automatically implemented /// for contexts, with one parameter for each dependency, to be /// provided in the same order as when the context is defined. -/// +/// /// ## Example -/// +/// /// ``` /// use std::sync::Arc; -/// +/// /// #[derive(Debug)] /// struct Foo; /// #[derive(Debug)] /// struct Bar; -/// +/// /// aerosol::define_context!( /// TestContext { /// foo: Arc, /// bar: Arc, /// } /// ); -/// +/// /// fn main() { /// TestContext::new( /// Arc::new(Foo), @@ -221,51 +221,51 @@ macro_rules! private_define_context { /// ); /// } /// ``` -/// +/// /// It is also possible to define a factory type to enable /// dependencies to be automatically created. -/// +/// /// When a factory is specified for a dependency, it will be /// omitted from the parameter list required by the context's /// constructor. Instead, the constructor will call the `build` /// method on the specified factory. -/// +/// /// To conditionally use a factory, or use different factories /// for the same dependency, define separate contexts, or /// call the factory manually and pass the result to the /// context's constructor in the normal way. -/// +/// /// ## Example -/// +/// /// ``` /// use std::sync::Arc; -/// +/// /// #[derive(Debug)] /// struct Foo; /// #[derive(Debug)] /// struct Bar; -/// +/// /// struct FooFactory; /// impl aerosol::Factory for FooFactory { /// type Object = Arc; /// fn build(_: ()) -> Result, anyhow::Error> { Ok(Arc::new(Foo)) } /// } -/// +/// /// aerosol::define_context!( /// TestContext { /// foo: Arc [FooFactory], /// bar: Arc, /// } /// ); -/// +/// /// fn main() { /// TestContext::new( /// Arc::new(Bar), /// ); /// } /// ``` -/// -/// +/// +/// #[macro_export] macro_rules! define_context { ($($input:tt)*) => ( diff --git a/src/interface.rs b/src/interface.rs index 35b6a78..5e1aea9 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -133,49 +133,49 @@ macro_rules! private_define_interface { /// Define a new interface. Used at any layer of your application /// to declare what dependencies are required by that part of the /// program. -/// +/// /// Interfaces follow a trait-like syntax, except that they may /// only contain "getter" methods of a particular form. The names /// of these methods are for the most part unimportant, but the /// return types are used to identify dependencies required for /// a context to implement this interface. -/// +/// /// ## Example -/// +/// /// ``` /// use std::sync::Arc; -/// +/// /// #[derive(Debug)] /// struct Foo; -/// +/// /// aerosol::define_interface!( /// TestInterface { /// fn foo(&self) -> Arc; /// } /// ); /// ``` -/// +/// /// Interfaces may also specify super-traits, which can themselves /// be interfaces. Interfaces do not need to explicitly list /// dependencies if they are transitively required by one of their /// super-traits, but repeating a dependency will still only /// require it to be provided once. -/// +/// /// ## Example -/// +/// /// ``` /// #![recursion_limit="128"] /// use std::sync::Arc; -/// +/// /// #[derive(Debug)] /// struct Foo; -/// +/// /// aerosol::define_interface!( /// FooInterface { /// fn foo(&self) -> Arc; /// } /// ); -/// +/// /// aerosol::define_interface!( /// TestInterface: FooInterface + Clone {} /// ); diff --git a/src/lib.rs b/src/lib.rs index 244b58c..20b9b8c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,53 +1,53 @@ //! # aerosol //! Simple dependency injection for Rust -//! +//! //! The two main exports of this crate are the `define_context` //! and `define_interface` macros. -//! +//! //! Contexts are containers for multiple dependencies, allowing //! them to be passed around as one with relative ease. Interfaces //! are specialized traits which place constraints on contexts, //! indicating exactly what dependencies a context must provide. -//! +//! //! Contexts are typically created at the top level of an application, //! as they specify exactly what concrete versions of all dependencies //! are going to be used. A single context is created with a precise //! set of depenencies, and is then threaded through the rest of the //! application as a generic parameter. -//! +//! //! Interfaces are used at every level of an application, as they //! allow each piece of code to independently specify what dependencies //! are required. Interfaces can "inherit" the dependencies of other //! interfaces, with the idea being that this inheritance will form //! a tree, such that there will be some "root interface" which contains //! the union of all dependencies required by the whole application. -//! +//! //! This pattern allows dependencies to be added or removed from any //! part of the application without having to modify the code at every //! level, to thread or un-thread the new or old dependencies through. -//! +//! //! ## Example -//! +//! //! ``` //! #![recursion_limit="128"] //! use std::sync::Arc; //! use std::fmt::Debug; -//! +//! //! // We will depend on some kind of logger //! trait Logger: Debug { //! fn log(&self, msg: &str); //! } -//! +//! //! // We have a specific implementation of a stdout logger //! #[derive(Debug)] //! struct StdoutLogger; -//! +//! //! impl Logger for StdoutLogger { //! fn log(&self, msg: &str) { //! println!("{}", msg); //! } //! } -//! +//! //! struct StdoutLoggerFactory; //! impl aerosol::Factory for StdoutLoggerFactory { //! type Object = Arc; @@ -55,29 +55,29 @@ //! Ok(Arc::new(StdoutLogger)) //! } //! } -//! +//! //! // Part of our application does some work //! aerosol::define_interface!( //! WorkerInterface { //! fn logger(&self) -> Arc; //! } //! ); -//! +//! //! fn do_work(iface: I) { //! iface.logger().log("Doing some work!"); //! } -//! +//! //! // Our application does multiple pieces of work //! aerosol::define_interface!( //! AppInterface: WorkerInterface + Clone {} //! ); -//! +//! //! fn run_app(iface: I, num_work_items: usize) { //! for _ in 0..num_work_items { //! do_work(iface.clone()); //! } //! } -//! +//! //! // At the very top level, we specify the implementations //! // of our dependencies. //! aerosol::define_context!( @@ -85,26 +85,25 @@ //! logger: Arc [StdoutLoggerFactory], //! } //! ); -//! +//! //! let context = AppContext::new().unwrap(); -//! +//! //! run_app(context, 4); //! ``` -//! +//! //! See the individual macro documentation for more details. #[doc(hidden)] pub extern crate tt_call; +mod context; +mod interface; mod join; mod parse; -mod interface; -mod context; - /// The building block for this crate. Automatically implemented /// for contexts providing a dependency of type `T`. -/// +/// /// Super-trait of all interfaces requiring a dependency of type /// `T`. pub trait Provide { @@ -113,7 +112,7 @@ pub trait Provide { /// Implement this trait to provide a convenient syntax for /// constructing implementations of dependencies. -pub trait Factory { +pub trait Factory { type Object; fn build(args: Args) -> Result; } diff --git a/src/main.rs b/src/main.rs index 5bc5b8a..f815f08 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ -#![recursion_limit="512"] +#![recursion_limit = "512"] +#![allow(clippy::blacklisted_name)] extern crate aerosol; #[macro_use] @@ -39,7 +40,9 @@ struct Bar; impl aerosol::Factory<(Bar,)> for FooFactory { type Object = Foo; - fn build(_: (Bar,)) -> Result { Ok(Foo) } + fn build(_: (Bar,)) -> Result { + Ok(Foo) + } } aerosol::define_context!( @@ -50,7 +53,6 @@ aerosol::define_context!( ); fn main() { - //trace_macros!(true); //aerosol::test_macro!(); tt_call! {