I'm trying to make a small trait for a Send&Sync shared ptr wrapper around a copy type. My initial implementation will use Arc<Mutex<T>>
but my goal is to eventually be able to substitute a different wrapper for a heapless implementation that I use in an embedded systems context (stm32).
My initial hurdle is using dyn Trait
with my own type. I've done it before for other structs that I've written but I'm unclear on what exactly the constraints are for using dyn Trait
as the type for my generic.
Below I have my initial wrapper, why can't I push a usize to the vector if I've implemented A
for usize?
pub mod shared_ptr {
pub trait SyncSharedPtr<T>: Send + Sync + Clone + Sized {
//fn new(inner: T) -> Self
fn locked<F: FnOnce(&mut T) -> R, R: Copy>(&self, func: F) -> R;
}
//an alias that i plan to change depending on the platform
pub type SPtr<T> = MArc<T>;
pub struct MArc<T: ?Sized> {
inner: std::sync::Arc<std::sync::Mutex<T>>
}
impl<T> MArc<T>
where
T: Send,
{
pub fn new(inner: T) -> Self {
Self { inner: std::sync::Arc::new(std::sync::Mutex::new(inner)) }
}
}
impl<T> SyncSharedPtr<T> for MArc<T>
where
T: Send,
{
fn locked<F: FnOnce(&mut T) -> R, R: Copy>(&self, func: F) -> R {
let mut g = self.inner.lock().unwrap();
func(&mut *g)
}
}
impl<T> Clone for MArc<T> {
fn clone(&self) -> Self {
MArc {
inner: std::sync::Arc::clone(&self.inner),
}
}
}
}
pub trait A {
fn a(&self);
}
impl A for usize {
fn a(&self) {}
}
use shared_ptr::{SPtr, SyncSharedPtr, MArc};
use std::sync::Arc;
use std::sync::Mutex;
fn main() {
//dyn works with Arc
let mut x: Vec<Arc<Mutex<dyn A>>> = Vec::new();
let p = Arc::new(Mutex::new(0usize));
p.lock().unwrap().a();
x.push(p.clone());
//why doesn't dyn work with my MArc type?
let y: Vec<MArc<dyn A>> = Vec::new();
let p = MArc::new(0usize);
p.locked(|i| i.a()); //does impl A
y.push(p);
let y: Vec<SPtr<dyn A>> = Vec::new();
let p = SPtr::new(0usize);
p.locked(|i| i.a()); //does ipml A
y.push(p);
}