Hello, do you have any ideas how to replicate api used in main
, but without min_specialization
?
#![feature(min_specialization)]
trait FieldAccess<T> {
fn get_ref_(&self) -> Option<&T>;
fn get_mut_(&mut self) -> Option<&mut T>;
}
impl<A, T> FieldAccess<T> for A {
default fn get_ref_(&self) -> Option<&T> {
None
}
default fn get_mut_(&mut self) -> Option<&mut T> {
None
}
}
trait Device {
fn get_ref<T>(&self) -> Option<&T>
where
Self: FieldAccess<T>,
{
<Self as FieldAccess<T>>::get_ref_(self)
}
fn get_mut<T>(&mut self) -> Option<&mut T>
where
Self: FieldAccess<T>,
{
<Self as FieldAccess<T>>::get_mut_(self)
}
}
#[derive(Debug, Clone, Copy)]
struct A;
#[derive(Debug, Clone, Copy)]
struct B;
#[derive(Debug, Clone, Copy)]
struct C;
#[derive(Debug, Clone, Copy)]
struct Foo(A, B);
#[derive(Debug, Clone, Copy)]
struct Bar(A, C);
impl Device for Foo {}
impl Device for Bar {}
impl FieldAccess<A> for Foo {
fn get_ref_(&self) -> Option<&A> {
Some(&self.0)
}
fn get_mut_(&mut self) -> Option<&mut A> {
Some(&mut self.0)
}
}
impl FieldAccess<B> for Foo {
fn get_ref_(&self) -> Option<&B> {
Some(&self.1)
}
fn get_mut_(&mut self) -> Option<&mut B> {
Some(&mut self.1)
}
}
impl FieldAccess<A> for Bar {
fn get_ref_(&self) -> Option<&A> {
Some(&self.0)
}
fn get_mut_(&mut self) -> Option<&mut A> {
Some(&mut self.0)
}
}
impl FieldAccess<C> for Bar {
fn get_ref_(&self) -> Option<&C> {
Some(&self.1)
}
fn get_mut_(&mut self) -> Option<&mut C> {
Some(&mut self.1)
}
}
fn main() {
let mut foo = Foo(A, B);
let mut bar = Bar(A, C);
println!("{:?}", foo.get_ref::<A>());
println!("{:?}", foo.get_mut::<B>());
println!("{:?}", foo.get_ref::<C>());
println!("{:?}", bar.get_ref::<A>());
println!("{:?}", bar.get_ref::<B>());
println!("{:?}", bar.get_ref::<C>());
}
Output:
Some(A)
Some(B)
None
Some(A)
None
Some(C)
I see Tracking Issue for `error_generic_member_access` · Issue #99301 · rust-lang/rust · GitHub that uses a stable technique with dynamic any
magic, but for my case I do not need dyn
access. Is there a way to have it using type system?
I also can manually implement FieldAccess
manually for all devices with all "components", but it feels very unproductive.