Hello there everyone,
I've been giving a shot on implementing a parser using Regex into a structure, and I'm trying to keep it copy-free as much as possible. Using references to the string used on the input is fine, but as soon as I've tried to use Cow's to allow the structure itself to become owned, I couldn't continue.
I'm trying the following (ignore unwraps as this is just a test):
use regex::Regex;
use std::borrow::Cow;
use lazy_static::lazy_static;
lazy_static! {
static ref VERSION_REGEX: Regex = Regex::new(r#"([a-z]):?([1-9])?"#).unwrap();
}
#[derive(Debug, Eq, PartialEq)]
struct Parsed<'a> {
alpha: Cow<'a, str>,
number: Option<Cow<'a, str>>,
}
impl<'a> Parsed<'a> {
fn parse(input: &str) -> Parsed {
let captures = VERSION_REGEX.captures(input).expect("Should work");
let alpha = captures.get(0).map(|x| x.as_str()).unwrap();
let version = captures.get(1).map(|x| x.as_str());
Parsed {
alpha: alpha.into(),
number: version.map(Cow::from),
}
}
fn to_owned(&self) -> Parsed<'static> {
Parsed {
alpha: self.alpha.to_owned(),
number: self.number.as_ref().map(Cow::to_owned)
}
}
}
fn main() {
let borrowed = Parsed::parse("a:2");
println!("{:#?}", borrowed);
let x : String = "a:1".into();
let borrowed = Parsed::parse(&x);
println!("{:#?}", borrowed);
let owned = {
let x : String = "a:1".into();
Parsed::parse(&x).to_owned()
};
println!("{:#?}", owned);
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/main.rs:30:31
|
30 | alpha: self.alpha.to_owned(),
| ^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 16:6...
--> src/main.rs:16:6
|
16 | impl<'a> Parsed<'a> {
| ^^
= note: ...so that the types are compatible:
expected &std::borrow::Cow<'_, str>
found &std::borrow::Cow<'a, str>
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the expression is assignable:
expected Parsed<'static>
found Parsed<'_>
error: aborting due to previous error
error: Could not compile `playground`.
To learn more, run the command again with --verbose.
Do I need to box my struct on the return? I thought that using Cow::to_owned
would allow me to make the inner data into String
and then there would be no need to box the Parsed
structure.