|
|
@ -67,76 +67,6 @@ pub struct Tree {
|
|
|
|
target: Rc<RefCell<Node>>,
|
|
|
|
target: Rc<RefCell<Node>>,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// impl Tree {
|
|
|
|
|
|
|
|
// fn new() -> Self {
|
|
|
|
|
|
|
|
// Node::empty().into()
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// /// Adds an element as a node as a child of the current node, then descends the tree to select
|
|
|
|
|
|
|
|
// /// that child node. This is similar to how pushing a value changes the top element of a stack.
|
|
|
|
|
|
|
|
// fn push(self, elem: Element) -> Self {
|
|
|
|
|
|
|
|
// if self.is_empty() {
|
|
|
|
|
|
|
|
// self.target.replace(Node::new(elem));
|
|
|
|
|
|
|
|
// self
|
|
|
|
|
|
|
|
// } else {
|
|
|
|
|
|
|
|
// let child = Node::child_of(Rc::clone(&self.target), elem);
|
|
|
|
|
|
|
|
// Tree {
|
|
|
|
|
|
|
|
// target: Rc::new(RefCell::new(child)),
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// /// Adds a child node with a given element value to the currently selected node without chaning
|
|
|
|
|
|
|
|
// /// our selection.
|
|
|
|
|
|
|
|
// fn append(self, elem: Element) -> Self {
|
|
|
|
|
|
|
|
// if self.is_empty() {
|
|
|
|
|
|
|
|
// self.target.replace(Node::new(elem));
|
|
|
|
|
|
|
|
// } else {
|
|
|
|
|
|
|
|
// let node = Node::child_of(Rc::clone(&self.target), elem);
|
|
|
|
|
|
|
|
// let child = Rc::new(RefCell::new(node));
|
|
|
|
|
|
|
|
// self.target.borrow_mut().children.push(child);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// self
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// /// Tells us whether or not the currently selected node is an empty node
|
|
|
|
|
|
|
|
// fn is_empty(&self) -> bool {
|
|
|
|
|
|
|
|
// self.target.borrow().elem == Element::Empty
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// fn parent(&self) -> Option<Self> {
|
|
|
|
|
|
|
|
// self.target.borrow().parent.as_ref().map(|parent| Self {
|
|
|
|
|
|
|
|
// target: Rc::clone(parent),
|
|
|
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// fn is_root(&self) -> bool {
|
|
|
|
|
|
|
|
// self.parent().is_none()
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// pub fn root(self) -> Self {
|
|
|
|
|
|
|
|
// match self.parent() {
|
|
|
|
|
|
|
|
// Some(parent) => parent.root(),
|
|
|
|
|
|
|
|
// None => self,
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// fn peek(&self) -> Element {
|
|
|
|
|
|
|
|
// self.target.borrow().elem.clone()
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// fn into_node(self) -> Node {
|
|
|
|
|
|
|
|
// self.into()
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// fn children(&self) -> ChildIter {
|
|
|
|
|
|
|
|
// ChildIter {
|
|
|
|
|
|
|
|
// parent: Rc::clone(&self.target),
|
|
|
|
|
|
|
|
// idx: 0,
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl fmt::Debug for Tree {
|
|
|
|
impl fmt::Debug for Tree {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
|
|
|
write!(f, "{:?}", self.target.borrow())
|
|
|
|
write!(f, "{:?}", self.target.borrow())
|
|
|
@ -179,164 +109,4 @@ impl From<Node> for Tree {
|
|
|
|
|
|
|
|
|
|
|
|
pub fn parse<S: AsRef<str>>(text: S) -> Result<Tree, ParseError> {
|
|
|
|
pub fn parse<S: AsRef<str>>(text: S) -> Result<Tree, ParseError> {
|
|
|
|
todo!()
|
|
|
|
todo!()
|
|
|
|
// let mut tree = Tree::new();
|
|
|
|
|
|
|
|
// for token in lex(text)? {
|
|
|
|
|
|
|
|
// match (tree.peek(), token) {
|
|
|
|
|
|
|
|
// (Element::Empty, Token::Ident(cmd)) => {
|
|
|
|
|
|
|
|
// tree = tree.push(Element::Command(cmd));
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// (Element::Command(_), Token::Ident(arg)) => {
|
|
|
|
|
|
|
|
// tree = tree.append(Element::Literal(arg));
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// _ => todo!(),
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// Ok(tree.root())
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// #[cfg(test)]
|
|
|
|
|
|
|
|
// mod tests {
|
|
|
|
|
|
|
|
// use super::*;
|
|
|
|
|
|
|
|
// use Token::Pipe;
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// fn ident<S: Into<String>>(s: S) -> Token {
|
|
|
|
|
|
|
|
// Token::Ident(s.into())
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// fn glob<S: Into<String>>(s: S) -> Token {
|
|
|
|
|
|
|
|
// Token::Glob(s.into())
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// macro_rules! lex {
|
|
|
|
|
|
|
|
// (
|
|
|
|
|
|
|
|
// $($name:ident: $line:literal $($token:expr)* ;)+
|
|
|
|
|
|
|
|
// ) => {
|
|
|
|
|
|
|
|
// $(
|
|
|
|
|
|
|
|
// #[test]
|
|
|
|
|
|
|
|
// fn $name() -> Result<(), Error> {
|
|
|
|
|
|
|
|
// let mut tokens = lex($line)?;
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// $(
|
|
|
|
|
|
|
|
// assert!(tokens.len() > 0);
|
|
|
|
|
|
|
|
// let front = tokens.remove(0);
|
|
|
|
|
|
|
|
// assert_eq!($token, front);
|
|
|
|
|
|
|
|
// )*
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// Ok(())
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// )*
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// lex! {
|
|
|
|
|
|
|
|
// single_token:
|
|
|
|
|
|
|
|
// "one"
|
|
|
|
|
|
|
|
// ident("one");
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// two_tokens:
|
|
|
|
|
|
|
|
// "ls one two"
|
|
|
|
|
|
|
|
// ident("ls") ident("one") ident("two");
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// leading_whitespace:
|
|
|
|
|
|
|
|
// " one"
|
|
|
|
|
|
|
|
// ident("one");
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// trailing_whitespace:
|
|
|
|
|
|
|
|
// "one "
|
|
|
|
|
|
|
|
// ident("one");
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// surrounding_whitespace:
|
|
|
|
|
|
|
|
// " one "
|
|
|
|
|
|
|
|
// ident("one");
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// internal_hyphen:
|
|
|
|
|
|
|
|
// "one-two"
|
|
|
|
|
|
|
|
// ident("one-two");
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// pipe:
|
|
|
|
|
|
|
|
// "|"
|
|
|
|
|
|
|
|
// Pipe;
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// pipeline:
|
|
|
|
|
|
|
|
// "one | two"
|
|
|
|
|
|
|
|
// ident("one") Pipe ident("two");
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// pipeline_2:
|
|
|
|
|
|
|
|
// "one |two"
|
|
|
|
|
|
|
|
// ident("one") Pipe ident("two");
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// simple_glob:
|
|
|
|
|
|
|
|
// "*"
|
|
|
|
|
|
|
|
// glob("*");
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// ext_glob:
|
|
|
|
|
|
|
|
// "*.rs"
|
|
|
|
|
|
|
|
// glob("*.rs");
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// mixed:
|
|
|
|
|
|
|
|
// "ls *.rs"
|
|
|
|
|
|
|
|
// ident("ls") glob("*.rs");
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// globby_pipeline:
|
|
|
|
|
|
|
|
// "ls *.rs | wc -l"
|
|
|
|
|
|
|
|
// ident("ls") glob("*.rs") Pipe ident("wc") ident("-l");
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// mid_glob:
|
|
|
|
|
|
|
|
// "a*b"
|
|
|
|
|
|
|
|
// glob("a*b");
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// #[test]
|
|
|
|
|
|
|
|
// fn empty_tree() {
|
|
|
|
|
|
|
|
// let root = Tree::new().root();
|
|
|
|
|
|
|
|
// assert!(root.is_root());
|
|
|
|
|
|
|
|
// assert_eq!(root.peek(), Element::Empty);
|
|
|
|
|
|
|
|
// assert_eq!(root.children().count(), 0);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// #[test]
|
|
|
|
|
|
|
|
// fn tree_root() {
|
|
|
|
|
|
|
|
// let root = Tree::new()
|
|
|
|
|
|
|
|
// .push(Element::Command(String::from("ls")))
|
|
|
|
|
|
|
|
// .root();
|
|
|
|
|
|
|
|
// assert!(root.is_root());
|
|
|
|
|
|
|
|
// assert_eq!(root.children().count(), 0);
|
|
|
|
|
|
|
|
// assert_eq!(root.into_node().elem, Element::Command(String::from("ls")));
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// #[test]
|
|
|
|
|
|
|
|
// fn tree_push() {
|
|
|
|
|
|
|
|
// let tree = Tree::new().push(Element::Command(String::from("ls")));
|
|
|
|
|
|
|
|
// assert_eq!(tree.peek(), Element::Command(String::from("ls")));
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// let tree = Tree::new()
|
|
|
|
|
|
|
|
// .push(Element::Command(String::from("ls")))
|
|
|
|
|
|
|
|
// .append(Element::Command(String::from("one")));
|
|
|
|
|
|
|
|
// assert_eq!(tree.peek(), Element::Command(String::from("ls")));
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// #[test]
|
|
|
|
|
|
|
|
// fn parse_args() {
|
|
|
|
|
|
|
|
// let res = parse("ls one two three");
|
|
|
|
|
|
|
|
// assert!(res.is_ok());
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// let tree = res.unwrap();
|
|
|
|
|
|
|
|
// assert_eq!(tree.peek(), Element::Command(String::from("ls")));
|
|
|
|
|
|
|
|
// assert_eq!(tree.children().count(), 3);
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// let mut args = tree.children();
|
|
|
|
|
|
|
|
// assert_eq!(
|
|
|
|
|
|
|
|
// args.next().unwrap().peek(),
|
|
|
|
|
|
|
|
// Element::Literal(String::from("one"))
|
|
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
// assert_eq!(
|
|
|
|
|
|
|
|
// args.next().unwrap().peek(),
|
|
|
|
|
|
|
|
// Element::Literal(String::from("two"))
|
|
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
// assert_eq!(
|
|
|
|
|
|
|
|
// args.next().unwrap().peek(),
|
|
|
|
|
|
|
|
// Element::Literal(String::from("three"))
|
|
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
// assert!(args.next().is_none());
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|