Skip to content

Instantly share code, notes, and snippets.

@oxalica
Last active March 25, 2021 19:48
Show Gist options
  • Save oxalica/dae005f39bb294e612967dccfe095543 to your computer and use it in GitHub Desktop.
Save oxalica/dae005f39bb294e612967dccfe095543 to your computer and use it in GitHub Desktop.
Extract value from nested tuple by given type
// https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=440c65898633c8dba89e0a036f049e95
use std::ops::Deref;
use std::marker::PhantomData;
#[repr(transparent)]
struct Getter<A, T>(T, PhantomData<A>);
impl<A, T, U> Deref for Getter<A, (T, U)> {
type Target = Getter<A, U>;
fn deref(&self) -> &Self::Target {
unsafe { std::mem::transmute::<&U, &Getter<A, U>>(&self.0.1) }
}
}
trait Has<T> {
fn get(&self) -> &T;
}
impl<T, U> Has<T> for Getter<T, (T, U)> {
fn get(&self) -> &T {
&self.0.0
}
}
fn getter<A, T>(tup: &T) -> &Getter<A, T> {
unsafe { std::mem::transmute::<&T, &Getter<A, T>>(tup) }
}
fn main() {
let tup = (1u32, ('2', ("3", (4i32, (5u8, (b"6", ()))))));
dbg!(getter::<i32, _>(&tup).get()); // 4
dbg!(getter::<&str, _>(&tup).get()); // "3"
dbg!(getter::<u32, _>(&tup).get()); // 1
// dbg!(getter::<i64, _>(&tup).get()); // compile error
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment