Skip to content

Instantly share code, notes, and snippets.

@rust-play
Created March 12, 2018 11:59
Show Gist options
  • Save rust-play/f5fd9f614eb147b9a6fd5a4b40e12733 to your computer and use it in GitHub Desktop.
Save rust-play/f5fd9f614eb147b9a6fd5a4b40e12733 to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
#![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