Skip to content

Instantly share code, notes, and snippets.

@MarchLiu
Created June 14, 2015 15:53
Show Gist options
  • Save MarchLiu/0300ec4ee7c115634c84 to your computer and use it in GitHub Desktop.
Save MarchLiu/0300ec4ee7c115634c84 to your computer and use it in GitHub Desktop.
//either parsec
pub fn either<T, R>(x: Parsec<T, R>, y: Parsec<T, R>)->Either<T, R> {
Either{
x: x,
y: y,
}
}
impl<'a, T, R> FnOnce<(&'a mut VecState<T>, )> for Either<T, R> {
type Output = Status<R>;
extern "rust-call" fn call_once(self, args: (&'a mut VecState<T>, )) -> Status<R> {
let (state, ) = args;
let pos = state.pos();
let mut fx = self.x;
let val = (fx)(state);
if val.is_ok() {
val
} else {
if pos == state.pos() {
let mut fy = self.y;
(fy)(state)
} else {
val
}
}
}
}
impl<'a, T, R> FnMut<(&'a mut VecState<T>, )> for Either<T, R> {
extern "rust-call" fn call_mut(&mut self, args: (&'a mut VecState<T>, )) -> Status<R> {
//self.call_once(args)
let (state, ) = args;
let pos = state.pos();
let val = (self.x)(state);
if val.is_ok() {
val
} else {
if pos == state.pos() {
(self.y)(state)
} else {
val
}
}
}
}
impl<T:'static, R:'static> Either<T, R> {
pub fn or(self, p:Parsec<T, R>) -> Self {
let re = either(Box::new(self), p);
re
}
}
#[test]
fn either_test_0() {
let mut state = VecState::from_iter("abc".chars().into_iter());
let a = one(Arc::new('a'));
let b = one(Arc::new('b'));
let e = &mut either(b, a);
let re = e(&mut state);
assert!(re.is_ok());
let data = re.unwrap();
assert_eq!(data, Arc::new('a'));
}
#[test]
fn either_test_1() {
let mut state = VecState::from_iter("abc".chars().into_iter());
let a = one(Arc::new('a'));
let b = one(Arc::new('b'));
let e = &mut either(a, b);
let re = e(&mut state);
assert!(re.is_ok());
let data = re.unwrap();
assert_eq!(data, Arc::new('a'));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment