Skip to content

Commit

Permalink
chore: release 0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
kkharji committed Apr 3, 2023
1 parent 3f7c0eb commit 1ff0426
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 104 deletions.
65 changes: 65 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Continuous integration

on:
push:
branches:
- master
pull_request:
branches:
- master


concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

env:
CARGO_TERM_COLOR: always
REDIS_RS_REDIS_JSON_PATH: "/tmp/librejson.so"

jobs:
check:
name: Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- run: cargo check --all-features

test:
name: Test Suite
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
redis:
- 6.2.6-v6
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v1
- name: Cache redis
id: cache-redis
uses: actions/cache@v2
with:
path: |
/usr/bin/redis-cli
/usr/bin/redis-server
key: ${{ runner.os }}-redis
- name: Cache RedisJSON
id: cache-redisjson
uses: actions/cache@v2
with:
path: |
/tmp/librejson.so
key: ${{ runner.os }}-redisjson
- name: Start Redis
uses: supercharge/[email protected]
with:
redis-image: redis/redis-stack
redis-version: ${{ matrix.redis }}
- run: cargo test
- run: cargo test --manifest-path lib/Cargo.toml
- run: cargo test --manifest-path lib/Cargo.toml --features json
- run: cargo test --manifest-path lib/Cargo.toml --features json,tokio-comp
- run: cargo test --all-features
124 changes: 65 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,51 +1,69 @@
# redis-om-rust
# redis-om
[![MIT licensed][mit-badge]][mit-url]
[![Build status][gh-actions-badge]][gh-actions-url]
[![Crates.io][crates-badge]][crates-url]

The Unofficial Redis Object mapping that makes it easy to model Redis data in Rust. _inspired by [redis-om-python](https://github.com/redis/redis-om-python)_
[crates-badge]: https://img.shields.io/crates/v/redis-om.svg
[crates-url]: https://crates.io/crates/redis-om
[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg
[mit-url]: LICENSE
[gh-actions-badge]: https://github.com/kkharji/redis-om/workflows/Continuous%20integration/badge.svg
[gh-actions-url]: https://github.com/kkharji/redis-om/actions?query=workflow%3A%22Continuous+integration%22

## State
A Rust/Redis ORM-style library that simplify the development process and reduce the amount of boilerplate code needed to build programs that leverage [redis] powerful capabilities and use cases.

Alpha
**Status**: *WIP, fully testsed, possible breaking changes, stay tuned*

## Async Support
**Features**

To enable asynchronous clients a feature for the underlying feature need to be activated.
- ORM-style API to define/manipulate [redis data structures] (e.g. hashes, json, streams) using [derive macros].
- Automatic serialization/desalinization between Redis data and rust objects.
- Interoperability with [serde](https://serde.rs/), e.g. using `rename`, `rename_all` or `serde`.
- Nested [hash datatype](#hash) support (e.g. `list.1` or nested models `account.balance` as keys).

```toml
# if you use tokio
redis-om = { version = "*", features = ["tokio-comp"] }
**Usage**

# if you use async-std
redis-om = { version = "*", features = ["async-std-comp"] }
```
- [Getting Started](#getting-started)
- [Using Redis's Hash Datatype](#hash)
- [Using Redis's Json Datatype](#json)
- [Using Redis's Stream Datatype](#stream)

**Roadmap**

- <kbd>0.1.0</kbd>
- [x] Enable users to define and derive Hash Model with most common methods
- [x] Enable users to define and derive JSON Model with most common methods
- [x] Enable users to define and derive streams with managers to publish-to/read-from them.
- [x] Support users to choose between asynchronous and synchronous runtime.
- <kbd>0.2.0</kbd>
- [ ] Enable Multi-Stream Manager Support to enable users to combine multiple `RedisModels`.
- [ ] Support Serializing/deserializing `HashModel` complex fields using serde.
- [ ] Support `RedisSearch` and provide query-building API.
- [ ] .....
- <kbd>0.3.0</kbd>
- [ ] Support validation of struct fields and enum values (most likely using [validator library]).
- [ ] .....


## Getting Started

## TLS Support
```toml
redis-om = { version = "*" }
# TLS support with async-std
redis-om = { version = "*", features = ["tls"] }

# if you use tokio
# async support with tokio
redis-om = { version = "*", features = ["tokio-comp"] }
# async support with async-std
redis-om = { version = "*", features = ["async-std-comp"] }
# TLS and async support with tokio
redis-om = { version = "*", features = ["tokio-native-tls-comp"] }

# if you use async-std
# TLS support with async-std
redis-om = { version = "*", features = ["async-std-tls-comp"] }
```

## Features

- [serde](https://serde.rs/) interop annotations such as `rename`, `rename_all`, alias and many more.
- Use struct methods todo all kind of crud and redis specific operations.
- Serialize [hash](#hash) model list-like and dict-like structs as prefix keys without needing JSON (i.e. list.1, account.balance).
- Support for [json](#json) datatype
- Support for [stream](#json) datatype

## Usage

- [hash datatype macro usage](#Hash)
- [Json datatype macro usage](#json)
- [Stream datatype macro usage](#Hash)
## Hash

### Hash

```rust
```rust ignore
use redis_om::HashModel;

#[derive(HashModel, Debug, PartialEq, Eq)]
Expand All @@ -71,7 +89,7 @@ let mut jane = Customer {
};

// Get client
let client = redis::Client::open("redis://127.0.0.1/").unwrap();
let client = redis_om::Client::open("redis://127.0.0.1/").unwrap();
// Get connection
let mut conn = client.get_connection().unwrap();

Expand All @@ -90,12 +108,12 @@ Customer::delete(&jane.id, &mut conn).unwrap();
assert_eq!(jane_db, jane);
```

### Json
## Json

redis-om support json data type through `redis_om::JsonModel`. It requires that the type
derives `serde::Deserialize` as well as `serde::Serialize`.

```rust
```rust ignore
use redis_om::JsonModel;
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -125,7 +143,7 @@ let mut john = Account {
};

// Get client
let client = redis::Client::open("redis://127.0.0.1/").unwrap();
let client = redis_om::Client::open("redis://127.0.0.1/").unwrap();
// Get connection
let mut conn = client.get_connection().unwrap();

Expand All @@ -143,11 +161,11 @@ Account::delete(&john.id, &mut conn).unwrap();

assert_eq!(john_db, john);
```
### Stream
## Stream

redis-om support json data type through `redis_om::StreamModel`. It requires that any nested type to derives `redis_om::RedisTransportValue`.

```rust
```rust ignore
use redis_om::{RedisTransportValue, StreamModel};

/// An enum of room service kind
Expand All @@ -169,7 +187,7 @@ pub struct RoomServiceEvent {
}

// Get client
let client = redis::Client::open("redis://127.0.0.1/").unwrap();
let client = redis_om::Client::open("redis://127.0.0.1/").unwrap();
// Get connection
let mut conn = client.get_connection().unwrap();

Expand Down Expand Up @@ -198,25 +216,13 @@ let read = manager.read(None, None, &mut conn).unwrap();
let incoming_event = read.first().unwrap();
// Get first incoming event data
let incoming_event_data = incoming_event.data::<RoomServiceEvent>().unwrap();
// Acknowledge that you received the event, so other in the consumer group don't get it
incoming_event.ack(&mut conn).unwrap();
// Acknowledge that you received the event, so other in the consumers don't get it
RoomServiceEventManager::ack(manager.group_name(), &[&incoming_event.id], &mut conn).unwrap();

assert_eq!(incoming_event.room, event.room);
assert_eq!(incoming_event_data.room, event.room);
```

## Roadmap

### 0.1.0

- [x] Hash Models
- [x] Json Model
- [x] Stream Model
- [x] Async support

### 0.2.0
- [ ] Multi Stream Manager
- [ ] stream model enum support
- [ ] serializing/deserializing hash model fields using serde for hash models
- [ ] Correctly support RedisSearch Integration with embedded types
- [ ] Internal managed connections, i.e. no requirement to pass conn around.
- [ ] Values Validation Support
[derive macros]: https://doc.rust-lang.org/reference/procedural-macros.html#derive-macros
[redis data structures]: https://redis.com/redis-enterprise/data-structures/
[redis]: https://redis.com
[validator library]: https://crates.io/crates/validator
21 changes: 13 additions & 8 deletions lib/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,32 +1,40 @@
[package]
name = "redis-om"
description = "The Unofficial Object mapping for Redis and Rust. Inspired by redis-om-python"
description = "Redis ORM-style library that simplify the development process and reduce the amount of boilerplate code needed to build programs that leverage [redis] powerful capabilities and use cases."
version = "0.1.0"
edition = "2021"
authors = [ "kkharji <[email protected]>"]
license = "MIT"
documentation = "https://docs.rs/redis-om"
homepage = "https://github.com/kkharji/redis-om-rust"
repository = "https://github.com/kkharji/redis-om-rust"
homepage = "https://github.com/kkharji/redis-om"
repository = "https://github.com/kkharji/redis-om"

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[features]
default = []
default = [ "tokio-comp" ]
### Enables json model support
json = [ "redis/json", "serde", "serde_json", "redis-om-macros/json" ]
##! ### Internal features
### Enables aio (used in tokio-native-tls-comp, tokio-comp)
aio = [ "redis/aio", "async-trait", "redis-om-macros/aio", "futures" ]
### Enables async-tokio support
tokio-comp = ["aio", "redis/tokio-comp"]
### Enables async-std support
async-std-comp = ["aio", "redis/async-std-comp"]
### Enables tls support
tls = ["redis/tls"]
### Enables async-tokio with tls support
tokio-native-tls-comp = [ "redis/tokio-native-tls-comp" ]
### Enables async-std with tls support
async-std-tls-comp = [ "redis/async-std-tls-comp" ]

[dependencies]
tap = { version = "1.0" }
thiserror = { version = "1.0" }
redis-om-macros = { path = "../macros" }
redis-om-macros = { version = "0.1.0", path = "../macros" }
redis = { version = "0.22.1" }
rusty_ulid = { version = "2.0.0" }
serde = { version = "1", features = [ "derive" ], optional = true }
Expand All @@ -38,6 +46,3 @@ futures = { version = "0.3.26", optional = true }
tokio = { version = "1.25.0", features = ["full"] }
trybuild = { version = "1.0.77" }
redis-swapplex = { version = "0.4.0" }

[[example]]
name = "readme"
23 changes: 0 additions & 23 deletions lib/examples/readme.rs

This file was deleted.

7 changes: 1 addition & 6 deletions lib/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
//! The Unofficial Redis Object mapping that makes it easy to model Redis data in Rust. _inspired by [redis-om-python](https://github.com/redis/redis-om-python)_
#![deny(missing_docs, unstable_features)]
// #![doc = include_str!("../README.md")]

#![doc = include_str!("../README.md")]
mod hash_model;
#[cfg(feature = "json")]
mod json_model;
Expand Down Expand Up @@ -72,7 +69,5 @@ pub use redis_model::RedisModel;
pub use redissearch_model::RedisSearchModel;
pub use stream_model::StreamModel;



#[cfg(feature = "aio")]
pub use async_trait::async_trait;
2 changes: 1 addition & 1 deletion lib/src/stream_model/async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use super::reply::StreamReadReply;
use super::transformers;

impl Message {
pub async fn ack<C: ConnectionLike + Send, Data: StreamModel>(
pub async fn ack<Data: StreamModel, C: ConnectionLike + Send>(
&self,
conn: &mut C,
) -> RedisResult<()> {
Expand Down
3 changes: 2 additions & 1 deletion lib/src/stream_model/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ mod cmds {
cmd.arg("CREATE")
.arg(S::stream_key())
.arg(s.group_name())
.arg("$");
.arg("$")
.arg("MKSTREAM");

Ok(cmd)
}
Expand Down
3 changes: 1 addition & 2 deletions lib/src/stream_model/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use super::reply::StreamReadReply;
use super::transformers;

impl Message {
pub fn ack<C: ConnectionLike, Data: StreamModel>(&self, conn: &mut C) -> RedisResult<()> {
pub fn ack<Data: StreamModel, C: ConnectionLike>(&self, conn: &mut C) -> RedisResult<()> {
Data::ack(&self.group, &[&self.id], conn)
}
}
Expand Down Expand Up @@ -140,4 +140,3 @@ pub trait StreamModel: Sized {
.map(transformers::stream_range_to_messages)?
}
}

2 changes: 1 addition & 1 deletion lib/tests/hash_model_async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ async fn expiring_keys() -> Result {

customer.save(&mut conn).await?;
customer.expire(1, &mut conn).await?;
std::thread::sleep(Duration::from_secs(1));
tokio::time::sleep(Duration::from_secs(3)).await;

let count = Cusotmer::all_pks(&mut conn).await?.count().await;

Expand Down
Loading

0 comments on commit 1ff0426

Please sign in to comment.