// all controls must implement this
trait Control: Sized {
fn size_x(&self) -> u32;
fn size_y(&self) -> u32;
fn size(&self) -> (u32, u32) {
return (self.size_x(), self.size_y());
}
}
// all checkboxes must implement this
trait Checkbox: Control {
fn checked(&self) -> bool;
fn set_checked(&mut self, is_checked: bool);
}
// our custom checkbox has a few supported shapes
#[derive(PartialEq, Copy, Clone)]
enum Shape {
Circle,
Square,
Octagon,
}
// and methods to set and retrieve the current shape
trait CustomCheckbox: Checkbox {
fn shape(&self) -> Shape;
fn set_shape(&mut self, shape: Shape);
}
// this is our custom checkbox control's in-memory representation
struct CoolCheckbox {
is_checked: bool,
checkbox_shape: Shape,
width: u32,
height: u32,
}
impl CoolCheckbox {
fn new() -> CoolCheckbox {
CoolCheckbox {
is_checked: false,
checkbox_shape: Shape::Square,
width: 25,
height: 30,
}
}
fn coolness_factor(&self) -> u32 {
42
}
}
impl Control for CoolCheckbox {
fn size_x(&self) -> u32 {
self.width
}
fn size_y(&self) -> u32 {
self.height
}
}
impl Checkbox for CoolCheckbox {
fn checked(&self) -> bool {
self.is_checked
}
fn set_checked(&mut self, is_checked: bool) {
self.is_checked = is_checked
}
}
impl CustomCheckbox for CoolCheckbox {
fn shape(&self) -> Shape {
self.checkbox_shape
}
fn set_shape(&mut self, shape: Shape) {
self.checkbox_shape = shape;
}
}
// doesn't care what kind of control it is
fn do_general<ControlT>(control: &ControlT) -> u32
where
ControlT: Control,
{
control.size_x() * control.size_y()
}
// doesn't need to know that it is your custom checkbox
fn do_something<CheckboxT>(checkbox: &CheckboxT) -> bool
where
CheckboxT: Checkbox,
{
let size_x = checkbox.size_x();
let checked = checkbox.checked();
//returns true if checkbox is wide enough and checked... for whatever reason
size_x > 40 && checked
}
// only works on checkboxes that implement CustomCheckbox
fn do_something_specifc<CheckboxT>(checkbox: &CheckboxT) -> &''static str
where
CheckboxT: CustomCheckbox,
{
let size_x = checkbox.size_x();
let checked = checkbox.checked();
let shape = checkbox.shape();
//returns true if checkbox is wide enough and checked... for whatever reason
if shape == Shape::Circle && size_x > 40 && checked {
"this CustomCheckbox rocks"
} else {
"this CustomCheckbox is only a little awesome"
}
}
// only works for our concrete implementation of CoolCheckbox
fn do_coolcheckbox_stuff(coolbox: &CoolCheckbox) -> u32 {
coolbox.coolness_factor() + 5
}
fn main() {
let mycheckbox = CoolCheckbox::new();
println!("general: {}", do_general(&mycheckbox));
println!("checkbox: {}", do_something(&mycheckbox));
println!("customcheckbox: {}", do_something_specifc(&mycheckbox));
println!("coolcheckbox: {}", do_coolcheckbox_stuff(&mycheckbox));
}
Comments