Skip to content

Instantly share code, notes, and snippets.

@art-solopov
Created November 8, 2018 11:34
Show Gist options
  • Save art-solopov/a72b79a6d5db6f9d7f3d93791063a7f9 to your computer and use it in GitHub Desktop.
Save art-solopov/a72b79a6d5db6f9d7f3d93791063a7f9 to your computer and use it in GitHub Desktop.
Rust "widget" tree structure with parents refs
use std::rc::{Rc, Weak};
use std::borrow::Borrow;
use std::cell::RefCell;
#[derive(Debug, Copy, Clone)]
enum FontWeight {
Normal,
Thin,
Bold
}
#[derive(Debug, Copy, Clone)]
enum FontStyle {
Normal,
Slanted,
Italic
}
#[derive(Debug, Copy, Clone)]
struct UIOptions {
font_weight: FontWeight,
font_style: FontStyle
}
impl Default for UIOptions {
fn default() -> UIOptions { UIOptions { font_weight: FontWeight::Normal, font_style: FontStyle::Normal } }
}
#[derive(Debug)]
struct Widget {
name: String,
children: RefCell<Vec<Rc<Widget>>>,
options: RefCell<UIOptions>,
parent: Option<Weak<Widget>>
}
impl Widget {
fn add_child(&self, child: Rc<Widget>) {
self.children.borrow_mut().push(child);
}
fn new(name: String, options: UIOptions, parent: Option<Rc<Widget>>) -> Rc<Widget> {
let widget = Widget {
name: name,
options: RefCell::new(options),
parent: parent.map(|opt| Rc::downgrade(&opt)),
children: RefCell::new(vec![])
};
Rc::new(widget)
}
fn new_root(name: String, options: UIOptions) -> Rc<Widget> {
Widget::new(name, options, Option::None)
}
fn new_child(name: String, options: UIOptions, parent: &Rc<Widget>) -> Rc<Widget> {
let child = Widget::new(name, options, Option::Some(parent.clone()));
let pt: &Widget = parent.borrow();
pt.add_child(Rc::clone(&child));
child
}
}
fn main() {
let root = Widget::new_root("Root widget".to_string(), UIOptions::default());
let child1 = Widget::new_child("Child widget".to_string(), UIOptions::default(), &root);
let child2 = Widget::new_child("Child widget".to_string(), UIOptions { font_style: FontStyle::Italic, ..Default::default() }, &root);
child1.options.borrow_mut().font_weight = FontWeight::Bold;
println!("{:?}", root);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment