Skip to content

Instantly share code, notes, and snippets.

@joseluis
Forked from rust-play/playground.rs
Last active April 13, 2019 18:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joseluis/2e0333a53d603d9fe83e4cd27439c2f6 to your computer and use it in GitHub Desktop.
Save joseluis/2e0333a53d603d9fe83e4cd27439c2f6 to your computer and use it in GitHub Desktop.
abstracting over fields with trait abuses: reddit.com/r/rust/comments/bc2w4m/announcing_rust_1340/eks8tq5/?context=3
trait Field {
type ValueType;
}
use std::marker::PhantomData as Marker;
struct X<T>(Marker<T>);
struct Y<T>(Marker<T>);
struct Z<T>(Marker<T>);
impl<T> Field for X<T> {
type ValueType = T;
}
impl<T> Field for Y<T> {
type ValueType = T;
}
impl<T> Field for Z<T> {
type ValueType = T;
}
trait HasField<F: Field> {
fn field(&self) -> &F::ValueType;
fn field_mut(&mut self) -> &mut F::ValueType;
}
#[derive(Debug, Default)]
struct Vec3<T>(T, T, T);
impl<T> HasField<X<T>> for Vec3<T> {
fn field(&self) -> &<X<T> as Field>::ValueType { &self.0 }
fn field_mut(&mut self) -> &mut <X<T> as Field>::ValueType { &mut self.0 }
}
impl<T> HasField<Y<T>> for Vec3<T> {
fn field(&self) -> &<Y<T> as Field>::ValueType { &self.1 }
fn field_mut(&mut self) -> &mut <Y<T> as Field>::ValueType { &mut self.1 }
}
impl<T> HasField<Z<T>> for Vec3<T> {
fn field(&self) -> &<Z<T> as Field>::ValueType { &self.2 }
fn field_mut(&mut self) -> &mut <Z<T> as Field>::ValueType { &mut self.2 }
}
fn main() {
let mut vec = Vec3::<u32>::default();
*HasField::<X<_>>::field_mut(&mut vec) = 1;
*HasField::<Y<_>>::field_mut(&mut vec) = 2;
*HasField::<Z<_>>::field_mut(&mut vec) = 3;
println!("{:?}", vec);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment