Skip to content

Commit

Permalink
refactor: use specialization to abstract store steps proof-of-concept
Browse files Browse the repository at this point in the history
  • Loading branch information
yxonic committed Jun 5, 2022
1 parent facdeef commit db4114f
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 7 deletions.
28 changes: 25 additions & 3 deletions rcommunity_core/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::marker::PhantomData;

use crate::{
error::Result,
markers::{ItemType, ReactionType, UserType},
markers::{store::Storable, ItemType, ReactionType, UserType},
store::{Store, Transaction},
};

Expand All @@ -25,7 +25,12 @@ impl<'store, TS: Store, TU: UserType, TI: ItemType, TR: ReactionType>
{
async fn push(&mut self, reaction: impl Into<TR>) -> Result<()> {
let mut txn = self.store.txn_begin().await?;
txn.put("".into(), "".into()).await?;
let r = reaction.into();

r.store_reaction(&mut txn, &self.user, &self.item).await?;
r.store_unique_index(&mut txn, &self.user, &self.item)
.await?;

txn.commit().await
}
}
Expand All @@ -35,7 +40,7 @@ mod test {
use std::marker::PhantomData;

use crate::{
markers::{ItemType, ReactionType, UserType},
markers::{ItemType, ReactionType, Unique, UserType},
store::memory::MemoryStore,
};

Expand All @@ -46,13 +51,30 @@ mod test {
impl UserType for User {}
struct Item(String);
impl ItemType for Item {}

enum Vote {
Upvote,
Downvote,
}
impl ReactionType for Vote {}
impl ItemType for Vote {}

struct Comment(String);
impl ReactionType for Comment {}
impl ItemType for Comment {}
impl Unique for Comment {}

#[tokio::test]
async fn test_reaction() {
let store = MemoryStore::default();
let mut client = UserItemUnboundedReactionClient {
store: &store,
user: User("1000".into()),
item: Item("2000".into()),
reaction_type: PhantomData::<Vote>,
};
client.push(Vote::Upvote).await.unwrap();

let mut client = UserItemUnboundedReactionClient {
store: &store,
user: User("1000".into()),
Expand Down
1 change: 1 addition & 0 deletions rcommunity_core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![feature(specialization)]
#![feature(associated_type_defaults)]
#![feature(negative_impls)]

Expand Down
48 changes: 45 additions & 3 deletions rcommunity_core/src/markers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,45 @@
pub trait UserType {}
pub trait ItemType {}
pub trait ReactionType {}
use async_trait::async_trait;

use crate::{error::Result, store::Transaction};

pub mod store;

pub trait UserType: Sync {}
pub trait ItemType: Sync {}
pub trait ReactionType: Sync {}

#[async_trait]
impl<T: ReactionType> store::Storable for T {
default async fn store_reaction(
&self,
txn: &mut impl Transaction,
user: &impl UserType,
item: &impl ItemType,
) -> Result<()> {
println!("store reaction");
Ok(())
}
default async fn store_unique_index(
&self,
txn: &mut impl Transaction,
user: &impl UserType,
item: &impl ItemType,
) -> Result<()> {
Ok(())
}
}

pub trait Unique {}

#[async_trait]
impl<T: ReactionType + Unique> store::Storable for T {
default async fn store_unique_index(
&self,
txn: &mut impl Transaction,
user: &impl UserType,
item: &impl ItemType,
) -> Result<()> {
println!("store unique index");
Ok(())
}
}
21 changes: 21 additions & 0 deletions rcommunity_core/src/markers/store.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use async_trait::async_trait;

use crate::{error::Result, store::Transaction};

use super::{ItemType, UserType};

#[async_trait]
pub trait Storable {
async fn store_reaction(
&self,
txn: &mut impl Transaction,
user: &impl UserType,
item: &impl ItemType,
) -> Result<()>;
async fn store_unique_index(
&self,
txn: &mut impl Transaction,
user: &impl UserType,
item: &impl ItemType,
) -> Result<()>;
}
2 changes: 1 addition & 1 deletion rcommunity_core/src/store/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub trait Store {
}

#[async_trait]
pub trait Transaction {
pub trait Transaction: Send {
async fn get(&self, key: String) -> Result<Option<String>>;
async fn put(&mut self, key: String, value: String) -> Result<()>;
async fn commit(&mut self) -> Result<()>;
Expand Down

0 comments on commit db4114f

Please sign in to comment.