I find myself playing around with warp.
I would like to pass a database Trait to a warp::Filter using static dispatch, such that the concrete database may vary.
I read that Send Sync are unsafe to implement, but I don't fully understand when it is appropriate to implement them.
Is it sound to implement Send Sync in this context:
use std::sync::{Arc, RwLock};
use warp::Filter;
use warp::reply::{json};
use serde_json::{Value};
pub trait IDatabase {
fn db_read(&self) -> Value;
fn db_write(&self, data: Value);
}
pub fn get_api_v0_test<T: IDatabase Send Sync>(
db: Arc<RwLock<T>>
) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> Clone {
warp::path!("api" / "v0" / "test")
.and(warp::get())
.map(move || {
json(&db.read().unwrap().db_read())
})
}
CodePudding user response:
I read that
Send Sync
areunsafe
to implement, but I don't fully understand when it is appropriate to implement them.
Because Send
and Sync
are automatically derived, it is only appropriate to derive them explicitely when wrapping raw pointers, usually because you're wrapping a native library, and after having made sure that the trait is appropriate for the underlying type.
Is it sound to implement Send Sync in this context:
I don't understand what you'd want to "implement Send Sync" on in this context.
pub trait IDatabase {
Rust is not C#, IWhatever
is not a thing.
CodePudding user response:
Yes, this example is completely sound!
As @trentcl and @Masklinn pointed out, I am in fact not implementing Send Sync
, I am simply requiring that any type T passed into the filter, implements the Send Sync
Traits, which is completely safe Rust.