diff --git a/Cargo.toml b/Cargo.toml index f1e767f..b5b2c02 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mongodb-macro" -version = "0.1.0" +version = "0.2.0" edition = "2021" description = "MongoDB Macro is a crate with macros for quickly creating structures to work with mongodb" keywords = [ "mongodb", "macro", "config", "clap" ] @@ -14,5 +14,8 @@ documentation = "https://docs.rs/mongodb-macro" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] + + +[dev-dependencies] clap = { version = "4.2.1", features = ["derive", "env"] } mongodb = ">=2" \ No newline at end of file diff --git a/README.md b/README.md index d3c1357..0610930 100644 --- a/README.md +++ b/README.md @@ -9,15 +9,53 @@ [mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg [mit-url]: LICENSE -mongodb-macro +# mongodb-macro -MongoDB Macro is a crate with macros for quickly creating structures to work with mongodb +MongoDB Macro is a crate with macros for quickly creating structures when working with mongodb. +In particular, macros are implemented for quick initialization of structures of the "factory" pattern. +The purpose of this crate is to reduce the amount of boilerplate code when initializing standard structures. -## Examples +## installation + +Install using cargo: + +`cargo install mongodb-macro` + +Make sure you also add to the project: + +> mongodb = "*" +> +> clap = { version = "*", features = ["derive", "env"] } + +## Usage + +### Macro: Client +```rust + +use mongodb::bson::Bson; + +// env DB_URL should contain a link to the mongodb url +mongodb_macro::client!(ClientFactory; ClientFactoryOpts); +// or with a specified env +// mongodb_macro::client!(ClientFactory; ClientFactoryOpts; "MONGO_DB_URL"); + +async fn main() -> std::io::Result<()> { + + let factory = ClientFactory::parse(); + + let client = factory.create().await.expect("failed to connect"); + + let db = client.database("demo"); + let collection = db.collection::("users"); + + ... +} +``` + +### Macro: Config ```rust -use mongodb::{Client, bson::Bson}; -use mongodb_macro::Parser; +use mongodb::bson::Bson; mongodb_macro::config!(Opts); // equivalent to @@ -41,6 +79,6 @@ async fn main() -> std::io::Result<()> { } ``` -Current version: 0.1.0 +Current version: 0.2.0 License: MIT diff --git a/README.tpl b/README.tpl index b0d4534..6d8b23b 100644 --- a/README.tpl +++ b/README.tpl @@ -9,7 +9,7 @@ [mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg [mit-url]: LICENSE -{{crate}} +# {{crate}} {{readme}} diff --git a/src/client.rs b/src/client.rs new file mode 100644 index 0000000..0bc9fea --- /dev/null +++ b/src/client.rs @@ -0,0 +1,96 @@ + + +/// Creates a new configuration structure to initialize the MongoDB client +/// +/// Create a new configuration structure to initialize the MongoDB client with a standard environment variable +/// +/// ``` +/// mongodb_macro::client_config!(Opts); +/// +/// fn main() { +/// std::env::set_var("DB_URL", "mongodb://root:root@localhost:27017"); +/// +/// let opts = Opts::parse(); +/// } +/// ``` +/// +/// Create a new configuration structure to initialize the MongoDB client with the specified environment variable +/// +/// ``` +/// mongodb_macro::client_config!(Opts; "MONGO_DB_URL"); +/// +/// fn main() { +/// std::env::set_var("MONGO_DB_URL", "mongodb://root:root@localhost:27017"); +/// +/// let opts = Opts::parse(); +/// } +/// ``` +#[macro_export] +macro_rules! client_config { + ($opts:ident) => ($crate::client_config!{$opts; "DB_URL"}); + + ($opts:ident; $db_url:tt) => { + use clap; + #[derive(Clone, Debug, PartialEq, Eq, ::clap::Parser)] + pub struct $opts { + /// env by default DB_URL + #[clap(env = $db_url)] + pub db_url: String, + } + }; +} + +/// Creates a new factory to create a MongoDB client +/// +/// Create mongodb client factory with standard environment variable for db url +/// +/// ``` +/// mongodb_macro::client!(ClientFactory; ClientFactoryOpts); +/// +/// fn main() { +/// std::env::set_var("DB_URL", "mongodb://root:root@localhost:27017"); +/// +/// let factory = ClientFactory::parse(); +/// +/// // let client = factory.create().await.expect("failed to connect"); +/// } +/// ``` +/// +/// Create mongodb client factory with specified environment variable for db url +/// +/// ``` +/// mongodb_macro::client!(ClientFactory; ClientFactoryOpts; "MONGO_DB_URL"); +/// +/// fn main() { +/// std::env::set_var("MONGO_DB_URL", "mongodb://root:root@localhost:27017"); +/// +/// let factory = ClientFactory::parse(); +/// +/// // let client = factory.create().await.expect("failed to connect"); +/// } +/// ``` +#[macro_export] +macro_rules! client { + ($client_builder:ident; $opts:ident) => ($crate::client!{$client_builder; $opts; "DB_URL"}); + ($client_builder:ident; $opts:ident; $db_url:tt) => { + use ::clap::Parser; + $crate::client_config!($opts; $db_url); + + pub struct $client_builder($opts); + + impl $client_builder { + fn parse() -> Self { + let opts = $opts::parse(); + Self(opts) + } + + pub fn config(&self) -> &$opts { + &self.0 + } + + pub async fn create(&self) -> Result<::mongodb::Client, ::mongodb::error::Error> { + ::mongodb::Client::with_uri_str(&self.0.db_url).await + } + } + }; +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index bd46326..91a76d5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,49 @@ /*! -MongoDB Macro is a crate with macros for quickly creating structures to work with mongodb +MongoDB Macro is a crate with macros for quickly creating structures when working with mongodb. +In particular, macros are implemented for quick initialization of structures of the "factory" pattern. +The purpose of this crate is to reduce the amount of boilerplate code when initializing standard structures. -# Examples +# installation + +Install using cargo: + +`cargo install mongodb-macro` + +Make sure you also add to the project: + +> mongodb = "*" +> +> clap = { version = "*", features = ["derive", "env"] } + +# Usage + +## Macro: Client +```no_run + +use mongodb::bson::Bson; + +// env DB_URL should contain a link to the mongodb url +mongodb_macro::client!(ClientFactory; ClientFactoryOpts); +// or with a specified env +// mongodb_macro::client!(ClientFactory; ClientFactoryOpts; "MONGO_DB_URL"); + +async fn main() -> std::io::Result<()> { + + let factory = ClientFactory::parse(); + + let client = factory.create().await.expect("failed to connect"); + + let db = client.database("demo"); + let collection = db.collection::("users"); + + ... +} +``` + +## Macro: Config ```no_run -use mongodb::{Client, bson::Bson}; -use mongodb_macro::Parser; +use mongodb::bson::Bson; mongodb_macro::config!(Opts); // equivalent to @@ -35,5 +73,6 @@ async fn main() -> std::io::Result<()> { #[doc(hidden)] pub mod opts; +/// Macros for creating MongoDB client configurations and factories from environment variables #[doc(hidden)] -pub use clap::Parser; \ No newline at end of file +pub mod client; \ No newline at end of file diff --git a/src/opts.rs b/src/opts.rs index 9964508..bf50943 100644 --- a/src/opts.rs +++ b/src/opts.rs @@ -3,8 +3,6 @@ /// Creating a configuration structure when using one database in a project: /// /// ``` -/// use mongodb_macro::Parser; -/// /// mongodb_macro::config!(Opts); /// /// fn main() { @@ -21,8 +19,6 @@ /// This sets the prefix to the environment variables. /// /// ``` -/// use mongodb_macro::Parser; -/// /// mongodb_macro::config!(Opts, "MONGO"); /// /// fn main() { @@ -37,8 +33,6 @@ /// Creating a configuration structure with explicit fields: /// /// ``` -/// use mongodb_macro::Parser; -/// /// mongodb_macro::config!(Opts; "MONGO_DB_NAME", "MONGO_COLLECTION_NAME","MONGO_DB_URL"); /// /// fn main() {