Skip to content

Commit

Permalink
Add client factory creation macro
Browse files Browse the repository at this point in the history
zeritiq committed Apr 14, 2023
1 parent 09a04d3 commit f04ffcf
Showing 6 changed files with 189 additions and 19 deletions.
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"
50 changes: 44 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -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::<Bson>("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
2 changes: 1 addition & 1 deletion README.tpl
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg
[mit-url]: LICENSE

{{crate}}
# {{crate}}

{{readme}}

96 changes: 96 additions & 0 deletions src/client.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
};
}
49 changes: 44 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -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::<Bson>("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;
pub mod client;
6 changes: 0 additions & 6 deletions src/opts.rs
Original file line number Diff line number Diff line change
@@ -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() {

0 comments on commit f04ffcf

Please sign in to comment.