#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct State {
pub focus: bool,
pub hover: bool,
pub disabled: bool,
pub checked: bool,
pub active: bool,
}
impl State {
pub const fn empty() -> Self {
Self { focus: false, hover: false, disabled: false, checked: false, active: false }
}
pub const fn focus() -> Self {
Self { focus: true, ..Self::empty() }
}
pub const fn disabled() -> Self {
Self { disabled: true, ..Self::empty() }
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Position {
pub index: usize,
pub sibling_count: usize,
pub parent_type: Option<String>,
}
impl Position {
pub fn new(index: usize, sibling_count: usize) -> Self {
Self { index, sibling_count, parent_type: None }
}
}
pub trait StyledNode {
fn type_name(&self) -> &str;
fn id(&self) -> Option<&str>;
fn classes(&self) -> Vec<&str>;
fn state(&self) -> State;
fn position(&self) -> Position;
}
#[derive(Debug, Clone)]
pub struct OwnedNode {
pub type_name: String,
pub id: Option<String>,
pub classes: Vec<String>,
pub state: State,
pub position: Position,
}
impl OwnedNode {
pub fn new(type_name: impl Into<String>) -> Self {
Self {
type_name: type_name.into(),
id: None,
classes: Vec::new(),
state: State::empty(),
position: Position::default(),
}
}
pub fn with_id(mut self, id: impl Into<String>) -> Self {
self.id = Some(id.into());
self
}
pub fn with_classes(mut self, classes: impl IntoIterator<Item = impl Into<String>>) -> Self {
self.classes = classes.into_iter().map(Into::into).collect();
self
}
pub fn with_state(mut self, state: State) -> Self {
self.state = state;
self
}
}
impl StyledNode for OwnedNode {
fn type_name(&self) -> &str {
&self.type_name
}
fn id(&self) -> Option<&str> {
self.id.as_deref()
}
fn classes(&self) -> Vec<&str> {
self.classes.iter().map(String::as_str).collect()
}
fn state(&self) -> State {
self.state
}
fn position(&self) -> Position {
self.position.clone()
}
}