Thank you, it works perfectly with Iterator<Item=T> :) .
But now I have another same error (all my program was working a few days ago, before the rust update).
You can see the code here :
use commandtree::{Command, Process, Job, CommandTree};
use commandtree::Condition::{OnSuccess, OnFail};
use std::io::BufReader;
use util::BufferedIterator;
use self::Token::{TokArg, TokPipe, TokAnd, TokOr, TokBackground, TokRedirectLeft, TokRedirectRight};
#[deriving(Clone, PartialEq,Show)]
pub enum Token {
TokArg(String),
TokPipe,
TokAnd,
TokOr,
TokBackground,
TokRedirectLeft,
TokRedirectRight,
}
rustlex! CommandLexer {
let SPACE = "\\s"+;
let PIPE = '|';
let BACKGROUND = '&';
let AND = "&&";
let OR = "||";
let REDIRECTLEFT = '<';
let REDIRECTRIGHT = '>';
let ID = ['a'-'z''A'-'Z''_']['a'-'z''A'-'Z''_''0'-'9']*;
let STR = '"' ([^'\\''"']|'\\'.)* '"';
PIPE => |_| Some(TokPipe)
BACKGROUND => |_| Some(TokBackground)
AND => |_| Some(TokAnd)
OR => |_| Some(TokOr)
REDIRECTLEFT => |_| Some(TokRedirectLeft)
REDIRECTRIGHT => |_| Some(TokRedirectRight)
ID => |lexer:&mut CommandLexer<R>| Some(TokArg(lexer.yystr()))
STR => |lexer:&mut CommandLexer<R>| {
let s = lexer.yystr();
let s = s.as_slice();
Some(TokArg(String::from_str(s.slice(1, s.len() - 1))))
}
}
pub fn parse_command(command: String) -> Option<CommandTree> {
let inp = BufReader::new(command.as_bytes());
let mut lexer = CommandLexer::new(inp);
let mut iter = BufferedIterator::new(&mut *lexer);
parse_s(&mut iter)
}
fn parse_s<I: Iterator<Token>>(tokens: &mut BufferedIterator<Token, I>) -> Option<CommandTree> {
match parse_c(tokens) {
Some(ref c) => {
let b = parse_b(tokens);
if tokens.actual() == None { Some(CommandTree {jobs: c.clone(), is_background: b}) } else { None }
},
None => None
}
}
fn parse_b<I: Iterator<Token>>(tokens: &mut BufferedIterator<Token, I>) -> bool {
match tokens.actual() {
Some(TokBackground) => {tokens.next(); true},
Some(_) | None => false
}
}
fn parse_c<I: Iterator<Token>>(tokens: &mut BufferedIterator<Token, I>) -> Option<Vec<Job>> {
match parse_c_recur(tokens, vec![]){
Some((ref process_list, ref mut buffer)) => {
buffer.push(Job {process_list: process_list.clone(), cond_to_exec: None});
let new_buffer = buffer.as_mut_slice();
new_buffer.reverse();
Some(new_buffer.to_vec())
}
None => None
}
}
fn parse_c_recur<I: Iterator<Token>>(tokens: &mut BufferedIterator<Token, I>, buffer: Vec<Job>) -> Option<(Vec<Process>, Vec<Job>)> {
match parse_j(tokens) {
Some(ref next_process_list) => match tokens.actual() {
Some(TokAnd) => {
tokens.next();
match parse_c_recur(tokens, buffer) {
Some((ref process_list, ref mut next_buffer)) => {
next_buffer.push(Job { process_list: process_list.clone(), cond_to_exec: Some(OnSuccess)});
Some((next_process_list.clone(), next_buffer.clone()))
}
None => None
}
},
Some(TokOr) => {
tokens.next();
match parse_c_recur(tokens, buffer) {
Some((ref process_list, ref mut next_buffer)) => {
next_buffer.push(Job { process_list: process_list.clone(), cond_to_exec: Some(OnFail)});
Some((next_process_list.clone(), next_buffer.clone()))
}
None => None
}
},
Some(_) | None => Some((next_process_list.clone(), buffer))
},
None => None
}
}