I currently have some code like the following:
use std::sync::{Arc, RwLock};
// Define traits
trait Child: Base {
fn method_a(&self);
}
trait Base {
fn method_b(&self);
}
// Struct implementing both traits
struct MyStruct {
something: i32,
};
impl Child for MyStruct {
fn method_a(&self) {
println!("Method A");
}
}
impl Base for MyStruct {
fn method_b(&self) {
println!("Method B");
}
}
fn do_some_processing(parent: &Arc<RwLock<dyn Child>>) -> Arc<RwLock<dyn Base>> {
//How do i do this?
}
fn main() {
let my_struct = Arc::new(RwLock::new(MyStruct));
let base = do_some_processing(&my_struct);
}
I want to limit the functions used after do_some_processing
has been called. That is the reason for the two traits.
Upcasting coercion is not yet stable. So this could work in +nightly
#![feature(trait_upcasting)]
use std::sync::{Arc, RwLock};
// Define traits
trait Child: Base {
fn method_a(&self);
}
trait Base {
fn method_b(&self);
}
// Struct implementing both traits
struct MyStruct {
something: i32,
}
impl Child for MyStruct {
fn method_a(&self) {
println!("Method A");
}
}
impl Base for MyStruct {
fn method_b(&self) {
println!("Method B");
}
}
fn do_some_processing(parent: &Arc<RwLock<dyn Child>>) -> Arc<RwLock<dyn Base>> {
parent.clone()
}
fn main() {
let my_struct: Arc<RwLock<dyn Child>> = Arc::new(RwLock::new(MyStruct { something: 42 }));
let base = do_some_processing(&my_struct);
}
---OR---
If you want to stick to stable you will need some wrapper
use std::sync::{Arc, RwLock};
// Define traits
trait Child: Base {
fn method_a(&self);
}
trait Base {
fn method_b(&self);
}
// Struct implementing both traits
struct MyStruct {
something: i32,
}
impl Child for MyStruct {
fn method_a(&self) {
println!("Method A");
}
}
impl Base for MyStruct {
fn method_b(&self) {
println!("Method B");
}
}
// Wrapper struct to manually upcast Child to Base
struct BaseWrapper {
inner: Arc<RwLock<dyn Child>>,
}
impl Base for BaseWrapper {
fn method_b(&self) {
self.inner.read().unwrap().method_b();
}
}
fn upcast(child: Arc<RwLock<dyn Child>>) -> Arc<RwLock<dyn Base>> {
Arc::new(RwLock::new(BaseWrapper { inner: child }))
}
fn main() {
let my_struct: Arc<RwLock<dyn Child>> = Arc::new(RwLock::new(MyStruct { something: 42 }));
let base = upcast(my_struct);
base.read().unwrap().method_b();
}