Skip to content

Instantly share code, notes, and snippets.

@irh
Last active August 28, 2016 11:16
Show Gist options
  • Save irh/920736939b7a7dffdb3d to your computer and use it in GitHub Desktop.
Save irh/920736939b7a7dffdb3d to your computer and use it in GitHub Desktop.
A Rust version of Sean Parent's example of concepts-based polymorphism in C++
// ...from 'Inheritance Is The Base Class of Evil'
use std::fmt;
use std::rc::Rc;
fn white_space(count: usize) -> String {
std::iter::repeat(' ').take(count).collect::<String>()
}
trait Drawable {
fn draw(&self, position: usize);
}
impl<T> Drawable for T where T: fmt::Display {
fn draw(&self, position: usize) {
println!("{}{}", white_space(position), self);
}
}
#[derive(Clone)]
struct Document {
data: Vec<Rc<Drawable>>
}
impl Document {
fn new() -> Document {
Document{ data: Vec::new() }
}
fn push<T: Drawable + 'static>(&mut self, x: T) {
self.data.push(Rc::new(x));
}
fn replace<T: Drawable + 'static>(&mut self, index: usize, x: T) {
self.data[index] = Rc::new(x);
}
}
impl Drawable for Document {
fn draw(&self, position: usize) {
println!("{}<document>", white_space(position));
for &ref e in self.data.iter() {
e.draw(position + 2);
}
println!("{}</document>", white_space(position));
}
}
struct History {
history: Vec<Document>
}
impl History {
fn new() -> History {
History{ history: vec![Document::new()] }
}
fn commit(&mut self) {
let clone = self.current().clone();
self.history.push(clone);
}
fn undo(&mut self) {
self.history.pop();
}
fn current(&mut self) -> &mut Document {
self.history.last_mut().unwrap()
}
}
struct MyClass;
impl Drawable for MyClass {
fn draw(&self, position: usize) {
println!("{}MyClass", white_space(position));
}
}
fn main() {
let mut h = History::new();
h.current().push(0);
h.current().push("Hello!");
h.commit();
h.current().draw(0);
println!("==============================");
let clone = h.current().clone();
h.current().push(clone);
h.current().push(MyClass);
h.current().replace(1, "World");
h.current().draw(0);
println!("==============================");
h.undo();
h.current().draw(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment