Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/azjezz/discern

Discern is a Rust library that implements the Command Query Responsibility Segregation (CQRS) pattern.
https://github.com/azjezz/discern

asynchronous concurrency cqrs cqrs-pattern cqrs-read cqrs-write rust

Last synced: 3 months ago
JSON representation

Discern is a Rust library that implements the Command Query Responsibility Segregation (CQRS) pattern.

Awesome Lists containing this project

README

        

# Discern

![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/azjezz/discern/ci.yml)
![License](https://img.shields.io/github/license/azjezz/discern)

Discern is a Rust library that implements the Command Query Responsibility Segregation (CQRS) pattern. It provides an easy-to-use framework for separating the write operations (commands) from the read operations (queries) in your Rust applications.

## Features

- **Command Handling**: Easily define commands that change the state of your system.
- **Query Handling**: Define queries that retrieve data without modifying the state.
- **Handler Registration**: Register command and query handlers using convenient macros.
- **Async Support**: Fully asynchronous handling of commands and queries using `async_trait`.

## Installation

Add `discern` to your `Cargo.toml`:

```toml
[dependencies]
discern = "0.1.0"
```

## Usage

Below is a simple example of how to use Discern to create a command bus that handles a `CreateUserCommand`:

```rust
use discern::async_trait;
use discern::command::Command;
use discern::command::CommandBus;
use discern::command::CommandHandler;
use discern::command_bus;

#[derive(Debug)]
struct CreateUserCommand {
username: String,
email: String,
}

#[derive(Debug)]
enum CreateUserError {
UsernameAlreadyExists,
EmailAlreadyExists,
}

#[derive(Debug)]
struct CreateUserMetadata(u32);

impl Command for CreateUserCommand {
type Metadata = CreateUserMetadata;
type Error = CreateUserError;
}

struct CreateUserCommandHandler {
// Add your dependencies here
}

#[async_trait]
impl CommandHandler for CreateUserCommandHandler {
async fn handle(&self, command: CreateUserCommand) -> Result {
// Add your command handling logic here, e.g.:
// let user = User::new(command.username, command.email);
// let id = self.repository.persist(user);
let id = 42;

Ok(CreateUserMetadata(id))
}
}

#[tokio::main]
async fn main() {
let command_bus: CommandBus = command_bus! {
CreateUserCommand => CreateUserCommandHandler {
// Add your dependencies here
},
};

let command = CreateUserCommand {
username: "alice".to_string(),
email: "[email protected]".to_string(),
};

match command_bus.dispatch(command).await {
Ok(metadata) => {
println!("User created with ID: {}", metadata.0);
}
Err(error) => {
eprintln!("Failed to create user: {:?}", err);
}
}
}
```

## Documentation

- [API Documentation](https://docs.rs/discern)

## License

Licensed under either of

* Apache License, Version 2.0
([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license
([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)

at your option.

## Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.