85 lines
1.8 KiB
Rust
85 lines
1.8 KiB
Rust
use std::{
|
|
iter::Map,
|
|
ops::{Deref, Range},
|
|
vec::IntoIter,
|
|
};
|
|
|
|
use super::{frame::Frame, theme::ColorSet};
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub enum Component {
|
|
String(String),
|
|
Goto(u16, u16),
|
|
Theme(ColorSet),
|
|
Padding(u16),
|
|
// Pre-formatted
|
|
Internal(String),
|
|
Repeated(char, u16),
|
|
Clear,
|
|
}
|
|
|
|
impl Component {
|
|
pub fn prepare_for(self, frame: &Frame) -> String {
|
|
match self {
|
|
Component::String(s) => s,
|
|
Component::Goto(x, y) => frame.goto(x, y),
|
|
Component::Theme(c) => c.to_string(),
|
|
Component::Clear => termion::clear::All.to_string(),
|
|
Component::Padding(len) => " ".repeat(len as usize),
|
|
Component::Internal(i) => i,
|
|
Component::Repeated(ch, len) => {
|
|
ch.to_string().repeat(len as usize)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct Components(pub Vec<Component>);
|
|
|
|
impl Deref for Components {
|
|
type Target = Vec<Component>;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
impl From<Vec<Component>> for Components {
|
|
fn from(value: Vec<Component>) -> Self {
|
|
Self(value)
|
|
}
|
|
}
|
|
|
|
impl From<Component> for Components {
|
|
fn from(value: Component) -> Self {
|
|
Self(vec![value])
|
|
}
|
|
}
|
|
|
|
impl Components {
|
|
pub fn str_len(&self) -> u16 {
|
|
(&self.0)
|
|
.into_iter()
|
|
.map(|comp| {
|
|
if let Component::String(s) = comp {
|
|
s.len() as u16
|
|
} else {
|
|
0
|
|
}
|
|
})
|
|
.sum()
|
|
}
|
|
|
|
pub fn concat_for(self, frame: &Frame) -> String {
|
|
self.0
|
|
.into_iter()
|
|
.map(|component| component.prepare_for(frame))
|
|
.collect::<String>()
|
|
}
|
|
|
|
pub fn push(&mut self, comp: Component) {
|
|
self.0.push(comp)
|
|
}
|
|
}
|