use derive_new::new; use getset::Getters; use std::str::FromStr; use serde_derive::{Deserialize, Serialize}; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)] pub enum Operator { Equal, NotEqual, LessThan, GreaterThan, LessThanOrEqual, GreaterThanOrEqual, } impl Operator { pub fn print(&self) -> String { match *self { Operator::Equal => "==".to_string(), Operator::NotEqual => "!=".to_string(), Operator::LessThan => "<".to_string(), Operator::GreaterThan => ">".to_string(), Operator::LessThanOrEqual => "<=".to_string(), Operator::GreaterThanOrEqual => ">=".to_string(), } } } impl FromStr for Operator { type Err = (); fn from_str(input: &str) -> Result::Err> { match input { "==" => Ok(Operator::Equal), "!=" => Ok(Operator::NotEqual), "<" => Ok(Operator::LessThan), ">" => Ok(Operator::GreaterThan), "<=" => Ok(Operator::LessThanOrEqual), ">=" => Ok(Operator::GreaterThanOrEqual), _ => Err(()), } } } #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)] pub enum Expression { Leaf(Leaf), Parenthesized(Box), Block(Box), Binary(Box), Path(Box), VariableReference(Variable), } impl Expression { crate fn print(&self) -> String { match self { Expression::Leaf(l) => l.print(), Expression::Parenthesized(p) => p.print(), Expression::Block(b) => b.print(), Expression::VariableReference(r) => r.print(), Expression::Path(p) => p.print(), Expression::Binary(b) => b.print(), } } crate fn as_string(&self) -> Option { match self { Expression::Leaf(Leaf::String(s)) | Expression::Leaf(Leaf::Bare(s)) => { Some(s.to_string()) } _ => None, } } } #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, new)] pub struct Block { crate expr: Expression, } impl Block { fn print(&self) -> String { format!("{{ {} }}", self.expr.print()) } } #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, new)] pub struct Parenthesized { crate expr: Expression, } impl Parenthesized { fn print(&self) -> String { format!("({})", self.expr.print()) } } #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Getters, new)] pub struct Path { #[get = "crate"] head: Expression, #[get = "crate"] tail: Vec, } impl Path { crate fn print(&self) -> String { let mut out = self.head.print(); for item in self.tail.iter() { out.push_str(&format!(".{}", item)); } out } } #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)] pub enum Variable { It, True, False, Other(String), } impl Variable { fn print(&self) -> String { match self { Variable::It => format!("$it"), Variable::True => format!("$true"), Variable::False => format!("$false"), Variable::Other(s) => format!("${}", s), } } } #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)] pub enum Leaf { String(String), Bare(String), #[allow(unused)] Boolean(bool), Int(i64), } impl Leaf { fn print(&self) -> String { match self { Leaf::String(s) => format!("{:?}", s), Leaf::Bare(s) => format!("{}", s), Leaf::Boolean(b) => format!("{}", b), Leaf::Int(i) => format!("{}", i), } } } #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, new)] pub struct Binary { crate left: Expression, crate operator: Operator, crate right: Expression, } impl Binary { fn print(&self) -> String { format!( "{} {} {}", self.left.print(), self.operator.print(), self.right.print() ) } } #[derive(Debug, Clone)] pub enum Flag { Shorthand(String), Longhand(String), } impl Flag { #[allow(unused)] fn print(&self) -> String { match self { Flag::Shorthand(s) => format!("-{}", s), Flag::Longhand(s) => format!("--{}", s), } } } #[derive(new, Debug, Clone)] pub struct ParsedCommand { crate name: String, crate args: Vec, } #[derive(new, Debug)] pub struct Pipeline { crate commands: Vec, } impl Pipeline { crate fn from_parts(command: ParsedCommand, rest: Vec) -> Pipeline { let mut commands = vec![command]; commands.extend(rest); Pipeline { commands } } }