#[derive(Default)]
pub struct Plugin {
pub status_bar: StatusBar,
pub sub_menu: Option<SubMenu>,
}
#[derive(Default, Debug, Clone)]
pub struct Line {
text: String,
href: String,
color: String,
font: String,
size: i64,
terminal: bool,
refresh: bool,
drop_down: bool,
length: i64,
trim: bool,
alternate: bool,
emojize: bool,
ansi: bool,
bash: String,
params: Vec<String>,
template_image: String,
image: String,
hr: bool,
}
#[derive(Default, Debug)]
pub struct Style {
pub color: String,
pub font: String,
pub size: i64,
pub length: i64,
pub trim: bool,
pub emojize: bool,
pub ansi: bool,
}
#[derive(Default, Debug)]
pub struct Cmd {
pub bash: String,
pub params: Vec<String>,
pub terminal: bool,
pub refresh: bool,
}
#[derive(Default, Debug)]
pub struct StatusBar {
pub lines: Vec<Line>,
}
pub struct SubMenu {
pub level: i64,
pub lines: Vec<SubMenuItem>,
}
pub enum SubMenuItem {
Line(Line),
SubMenu(Box<SubMenu>),
}
impl Plugin {
pub fn new() -> Self {
Plugin::default()
}
pub fn set_status_line(&mut self, line: Line) -> &mut Self {
self.status_bar.lines.push(line);
self
}
pub fn set_sub_menu(&mut self, sub_menu: SubMenu) -> &mut Self {
self.sub_menu = Some(sub_menu);
self
}
pub fn render(&self) {
print!("{}", self.to_string());
}
}
impl std::string::ToString for Plugin {
fn to_string(&self) -> String {
let mut output = String::from("");
for line in self.status_bar.lines.iter().as_ref() {
let line_str = line.to_string();
output = format!("{}{}\n", output, line_str);
}
output = format!("{}---\n", output);
if self.sub_menu.is_some() {
let curr_sm = self.sub_menu.as_ref().unwrap();
output = format!("{}{}", output, render_sub_menu(curr_sm));
}
return output;
}
}
impl SubMenu {
pub fn new() -> Self {
SubMenu {
level: 0,
lines: vec![],
}
}
pub fn add_line(&mut self, line: Line) -> &mut Self {
self.lines.push(SubMenuItem::Line(line));
self
}
pub fn add_sub_menu(&mut self, sub_menu: SubMenu) -> &mut Self {
self.lines.push(SubMenuItem::SubMenu(Box::new(sub_menu)));
self
}
pub fn add_hr(&mut self) -> &mut Self {
let line = Line {
text: "---".to_string(),
hr: true,
..Default::default()
};
self.lines.push(SubMenuItem::Line(line));
self
}
}
impl Line {
pub fn new<T: Into<String>>(text: T) -> Self {
Line {
text: text.into(),
..Default::default()
}
}
pub fn set_text<T: Into<String>>(&mut self, text: T) -> &mut Self {
self.text = text.into();
self
}
pub fn set_style(&mut self, style: Style) -> &mut Self {
self.color = style.color;
self.font = style.font;
self.size = style.size;
self.length = style.length;
self.trim = style.trim;
self.emojize = style.emojize;
self.ansi = style.ansi;
self
}
pub fn set_command(&mut self, cmd: Cmd) -> &mut Self {
self.bash = cmd.bash;
self.params = cmd.params;
self.terminal = cmd.terminal;
self.refresh = cmd.refresh;
self
}
pub fn set_href<T: Into<String>>(&mut self, href: T) -> &mut Self {
self.href = href.into();
self
}
pub fn set_color<T: Into<String>>(&mut self, color: T) -> &mut Self {
self.color = color.into();
self
}
pub fn set_font<T: Into<String>>(&mut self, font: T) -> &mut Self {
self.font = font.into();
self
}
pub fn set_size(&mut self, size: i64) -> &mut Self {
self.size = size;
self
}
pub fn set_bash<T: Into<String>>(&mut self, bash: T) -> &mut Self {
self.bash = bash.into();
self
}
pub fn set_params(&mut self, params: Vec<String>) -> &mut Self {
self.params = params;
self
}
pub fn set_terminal(&mut self, terminal: bool) -> &mut Self {
self.terminal = terminal;
self
}
pub fn set_refresh(&mut self, refresh: bool) -> &mut Self {
self.refresh = refresh;
self
}
pub fn set_drop_down(&mut self, drop_down: bool) -> &mut Self {
self.drop_down = drop_down;
self
}
pub fn set_length(&mut self, length: i64) -> &mut Self {
self.length = length;
self
}
pub fn set_trim(&mut self, trim: bool) -> &mut Self {
self.trim = trim;
self
}
pub fn set_alternate(&mut self, alternate: bool) -> &mut Self {
self.alternate = alternate;
self
}
pub fn set_emojize(&mut self, emojize: bool) -> &mut Self {
self.emojize = emojize;
self
}
pub fn set_ansi(&mut self, ansi: bool) -> &mut Self {
self.ansi = ansi;
self
}
}
impl std::string::ToString for Line {
fn to_string(&self) -> String {
let mut res = vec![self.text.to_string()];
let mut options: Vec<String> = vec!["|".to_string()];
options.append(&mut render_style_options(self));
options.append(&mut render_misc_options(self));
options.append(&mut render_command_options(self));
if options.len() > 1 {
res.append(&mut options);
}
return res.join(" ");
}
}
impl Style {
pub fn new() -> Self {
Style::default()
}
}
fn render_sub_menu(sub_menu: &SubMenu) -> String {
let mut output = String::new();
let mut prefix = String::new();
if sub_menu.level > 0 {
prefix = format!("{} ", "--".repeat(sub_menu.level as usize))
}
for line in sub_menu.lines.iter().as_ref() {
match line {
SubMenuItem::Line(current_line) => {
if current_line.hr {
output = format!("{}{}{}\n", output, prefix.trim(), current_line.to_string());
} else {
output = format!("{}{}{}\n", output, prefix, current_line.to_string());
}
}
SubMenuItem::SubMenu(current_sub_m) => {
output = format!("{}{}", output, render_sub_menu(¤t_sub_m))
}
}
}
output
}
fn render_misc_options(line: &Line) -> Vec<String> {
let mut misc_opts = vec![];
if line.href != "" {
misc_opts.push(format!("href='{}'", line.href));
}
if line.drop_down {
misc_opts.push(format!("dropdown='{}'", line.drop_down));
}
if line.alternate {
misc_opts.push(format!("alternate='{}'", line.alternate));
}
misc_opts
}
fn render_style_options(line: &Line) -> Vec<String> {
let mut style_opts = vec![];
if line.color != "" {
style_opts.push(format!(r#"color="{}""#, line.color));
}
if line.font != "" {
style_opts.push(format!(r#"font="{}""#, line.font));
}
if line.size > 0 {
style_opts.push(format!("size={}", line.size));
}
if line.length > 0 {
style_opts.push(format!("length={}", line.length));
}
if line.trim {
style_opts.push(format!("trim={}", line.trim));
}
if line.emojize {
style_opts.push(format!("emojize={}", line.emojize));
}
if line.ansi {
style_opts.push(format!("ansi={}", line.ansi));
}
style_opts
}
fn render_command_options(line: &Line) -> Vec<String> {
let mut command_opts = vec![];
if line.bash != "" {
command_opts.push(format!(r#"bash="{}""#, line.bash));
}
if line.params.len() > 0 {
for i in 0..line.params.len() {
command_opts.push(format!("param{}={}", i, line.params[i]));
}
}
if line.terminal {
command_opts.push(format!("terminal={}", line.terminal));
}
if line.refresh {
command_opts.push(format!("refresh={}", line.refresh));
}
command_opts
}
#[test]
fn test_render_command_options() {
let mut line = Line::new("here is a test".to_string());
line.set_bash("echo test".to_string())
.set_params(vec!["params1".to_string(), "params2".to_string()])
.set_refresh(true);
let resp = render_command_options(&line);
assert_eq!(resp[0], r#"bash="echo test""#.to_string());
assert_eq!(resp[1], r#"param0=params1"#.to_string());
assert_eq!(resp[2], r#"param1=params2"#.to_string());
assert_eq!(resp[3], "refresh=true".to_string());
}
#[test]
fn test_line_to_string() {
let mut line = Line::new("here is a test".to_string());
line.set_bash("echo test".to_string())
.set_color("red".to_string())
.set_params(vec!["params1".to_string(), "params2".to_string()])
.set_refresh(true);
let resp = line.to_string();
assert_eq!(resp, r#"here is a test | color="red" bash="echo test" param0=params1 param1=params2 refresh=true"#.to_string());
}