p.and_then(q) should Cow p's output
asajeffrey opened this issue · comments
The type for and_then should be that it Cow's p's output. For instance:
let p = character(char::is_alphabetic).plus().buffer();
let q = character(char::is_numeric).star().buffer();
p.and_then(q).parse("abc1").unContinue().parse("23!")
should return (Owned(String::from("abc")),Owned(String::from("123")))
. At the moment. "abc"
is borrowed rather than owned, which is producing lifetime issues.
After a bit of bouncing around on the #rust
irc, a possible solution is https://play.rust-lang.org/?gist=bcdf295150adc2a59519, which saves/restores transient data to persistent data. Internally, AndThenStatefulParser
could store T::Persistent
, which in the case of Cow<'a,str>
would be String
.
OK, got a test which fails:
fn test_different_lifetimes2() {
use std::borrow::Cow;
use std::borrow::Cow::{Owned, Borrowed};
fn ignore() {}
fn go<'a, 'b, P>(fst: &'a str, snd: &'b str, parser: P)
where P: Copy + for<'c> Committed<&'c str, Output = (Cow<'c,str>, Cow<'c,str>)>
{
match parser.init().parse(fst) {
Continue("", parsing) => match parsing.parse(snd) {
Done("!", (Owned(fst), Owned(snd))) => {
assert_eq!(fst, "abc");
assert_eq!(snd, "123");
},
oops => panic!("Shouldn't happen 2 {:?}", oops),
},
Done("!", (Borrowed(fst), Borrowed(snd))) => {
assert_eq!(fst, "abc");
assert_eq!(snd, "123");
},
oops => panic!("Shouldn't happen 1 {:?}", oops),
}
}
let parser = character(char::is_alphabetic).star(ignore).buffer()
.and_then(character(char::is_numeric).star(ignore).buffer());
go("abc123!", "!", parser);
go("abc1", "23!", parser);
go("ab", "c123!", parser);
}
In fact I'm a bit surprised this even type-checks.
Checked in the test, it's test_different_lifetimes2
.
Fixed in v0.4.0.