Created
March 12, 2018 11:59
-
-
Save rust-play/f5fd9f614eb147b9a6fd5a4b40e12733 to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(specialization)] | |
pub struct MemberBase { | |
id: u32, | |
} | |
impl MemberBase { | |
pub fn id(&self) -> u32 { self.id } | |
} | |
pub trait UiMemberSpecialization { | |
fn size(&self) -> (u32, u32); | |
} | |
pub trait UiMember { | |
fn id(&self) -> u32; | |
fn size(&self) -> (u32, u32); | |
fn as_member_base(&self) -> &MemberBase; | |
fn as_member_base_mut(&mut self) -> &mut MemberBase; | |
fn is_control(&self) -> Option<&UiControl>; | |
fn is_control_mut(&mut self) -> Option<&mut UiControl>; | |
} | |
pub struct Member<T: UiMemberSpecialization + Sized> { | |
base: MemberBase, | |
inner: T, | |
} | |
impl <T: UiMemberSpecialization + Sized> UiMember for Member<T> { | |
fn id(&self) -> u32 { self.base.id } | |
fn size(&self) -> (u32, u32) { self.inner.size() } | |
fn as_member_base(&self) -> &MemberBase { &self.base } | |
fn as_member_base_mut(&mut self) -> &mut MemberBase { &mut self.base } | |
default fn is_control(&self) -> Option<&UiControl> { None } | |
default fn is_control_mut(&mut self) -> Option<&mut UiControl> { None } | |
} | |
// ========================================================= | |
pub struct ControlBase { | |
name: String | |
} | |
impl ControlBase { | |
pub fn name(&self) -> &str { self.name.as_ref() } | |
} | |
pub trait UiControlSpecialization: UiMemberSpecialization { | |
fn parent_mut(&mut self) -> Option<&mut UiMember>; | |
} | |
pub trait UiControl: UiMember { | |
fn name(&self) -> &str; | |
fn parent_mut(&mut self) -> Option<&mut UiMember>; | |
fn as_member(&self) -> &UiMember; | |
fn as_member_mut(&mut self) -> &mut UiMember; | |
fn as_control_base(&self) -> &ControlBase; | |
fn as_control_base_mut(&mut self) -> &mut ControlBase; | |
} | |
pub struct Control<T: UiControlSpecialization + Sized> { | |
base: ControlBase, | |
inner: T, | |
} | |
impl <T: UiControlSpecialization + Sized> UiMemberSpecialization for Control<T> { | |
fn size(&self) -> (u32, u32) { | |
self.inner.size() | |
} | |
} | |
impl <T: UiControlSpecialization + Sized> UiControl for Member<Control<T>> { | |
fn name(&self) -> &str { self.inner.base.name() } | |
fn parent_mut(&mut self) -> Option<&mut UiMember> { self.inner.inner.parent_mut() } | |
fn as_member(&self) -> &UiMember { self } | |
fn as_member_mut(&mut self) -> &mut UiMember { self } | |
fn as_control_base(&self) -> &ControlBase { &self.inner.base } | |
fn as_control_base_mut(&mut self) -> &mut ControlBase { &mut self.inner.base } | |
} | |
impl <T: UiControlSpecialization + Sized> UiMember for Member<Control<T>> { | |
fn is_control(&self) -> Option<&UiControl> { Some(self) } | |
fn is_control_mut(&mut self) -> Option<&mut UiControl> { Some(self) } | |
} | |
// ========================================================== | |
pub trait UiWindowSpecialization: UiMemberSpecialization { | |
fn with_name(name: String) -> Self; | |
fn on_top(&mut self); | |
} | |
pub trait UiWindow: UiMember { | |
fn on_top(&mut self); | |
fn as_member(&self) -> &UiMember; | |
fn as_member_mut(&mut self) -> &mut UiMember; | |
} | |
impl <T: UiWindowSpecialization + Sized> UiWindow for Member<T> { | |
fn on_top(&mut self) { self.inner.on_top() } | |
fn as_member(&self) -> &UiMember { self } | |
fn as_member_mut(&mut self) -> &mut UiMember { self } | |
} | |
impl <T: UiWindowSpecialization + Sized> Member<T> { | |
pub fn with_name(name: String) -> Box<Self> { | |
Box::new(Member {base: MemberBase {id: 42}, inner: T::with_name(name)}) | |
} | |
} | |
// ========================================================== | |
pub trait UiButtonSpecialization: UiControlSpecialization { | |
fn with_label(label: String) -> Self; | |
fn on_click(&mut self); | |
} | |
pub trait UiButton: UiControl { | |
fn on_click(&mut self); | |
fn as_control(&self) -> &UiControl; | |
fn as_control_mut(&mut self) -> &mut UiControl; | |
} | |
impl <T: UiButtonSpecialization + Sized> UiButton for Member<Control<T>> { | |
fn on_click(&mut self) { self.inner.inner.on_click(); } | |
fn as_control(&self) -> &UiControl { self } | |
fn as_control_mut(&mut self) -> &mut UiControl { self } | |
} | |
impl <T: UiButtonSpecialization + Sized> Member<Control<T>> { | |
pub fn with_label(label: String) -> Box<Self> { | |
Box::new(Member {base: MemberBase {id: 55}, inner: Control { base: ControlBase {name: "Oops".to_string() }, inner: T::with_label(label) }}) | |
} | |
} | |
// ========================================================== | |
pub struct WindowSpecialization { | |
size: (u32, u32) | |
} | |
impl UiWindowSpecialization for WindowSpecialization { | |
fn on_top(&mut self) { println!("Window on top!") } | |
fn with_name(name: String) -> Self { WindowSpecialization { size: (11, 11) } } | |
} | |
impl UiMemberSpecialization for WindowSpecialization { | |
fn size(&self) -> (u32, u32) { self.size } | |
} | |
pub type Window = Member<WindowSpecialization>; | |
// ========================================================== | |
pub struct ButtonSpecialization { | |
size: (u32, u32) | |
} | |
impl UiButtonSpecialization for ButtonSpecialization { | |
fn on_click(&mut self) { println!("clicked!") } | |
fn with_label(label: String) -> Self { ButtonSpecialization {size: (99, 99)} } | |
} | |
impl UiControlSpecialization for ButtonSpecialization { | |
fn parent_mut(&mut self) -> Option<&mut UiMember> { None } | |
} | |
impl UiMemberSpecialization for ButtonSpecialization { | |
fn size(&self) -> (u32, u32) { self.size } | |
} | |
pub type Button = Member<Control<ButtonSpecialization>>; | |
// ========================================================== | |
fn main() { | |
let mut window = Window::with_name("W".to_string()); | |
let mut button = Button::with_label("B".to_string()); | |
let mut window: &mut UiWindow = window.as_mut(); | |
let mut window: &mut UiMember = window.as_member_mut(); | |
let mut window = window.as_member_base_mut(); | |
let mut window: &mut Window = unsafe { ::std::mem::transmute(window) }; | |
let mut button: &mut UiButton = button.as_mut(); | |
let mut button: &mut UiControl = button.as_control_mut(); | |
let mut button: &mut UiMember = button.as_member_mut(); | |
let mut button = button.as_member_base_mut(); | |
let mut button: &mut Button = unsafe { ::std::mem::transmute(button) }; | |
window.on_top(); | |
button.on_click(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment