Hi folks,
I have a few structs with lifetimes (First
and Second
) with parsed data. And I have functions parse_data
to parse data (I use split_once
as a good example because it leaves lifetime).
Individually the First
and Second
work great:
let data = "a/b/c/d/e/f/g".to_owned();
let cf = "/".to_owned();
let x = First::parse_data(&data, &cf);
The problem is when I want to use them in a large struct in a form of a building pattern:
let data = "a/b/c/d/e/f/g".to_owned();
let cf = "/".to_owned();
let x = Everything::new(&data, &cf).set_first();
I get lifetime issues. Easy solution would be to modify First::parse_data
and Second::parse_data
so they take owned arguments but they're more useful when they just borrow.
Could you please tell me if there is another solution?
Thank you.
Full code:
#[derive(Clone, Debug, Default, Eq, PartialEq)]
struct First<'a> {
parsed: &'a str,
}
impl<'a, 'b> First<'a> {
fn parse_data(data: &'a str, cf: &'b str) -> (Option<Self>, String) {
match data.split_once(cf) {
None => (None, data.to_owned()),
Some((parsed,out)) => (Some(Self { parsed }), out.to_owned() )
}
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
struct Second<'a> {
parsed: &'a str,
}
impl<'a, 'b> Second<'a> {
fn parse_data(data: &'a str, cf: &'b str) -> (Option<Self>, String) {
match data.split_once(cf) {
None => (None, data.to_owned()),
Some((parsed,out)) => (Some(Self { parsed }), out.to_owned() )
}
}
}
struct MyError;
#[derive(Clone, Debug, Default, Eq, PartialEq)]
struct Everything<'a> {
first: Option<First<'a>>,
second: Option<First<'a>>,
unparsed: String,
cf: String,
}
impl<'a, 'b> Everything<'a> {
fn new(data: &'a str, cf: &'b str) -> Self {
Self {
unparsed: data.to_owned(),
cf: cf.to_owned(),
..Default::default()
}
}
fn set_first(mut self) -> Result<Self, MyError> {
//////////////////////////////////////////// THIS IS A PROBLEM
if let (first, unparsed) = First::parse_data(&self.unparsed, &self.cf) {
self.first = first;
self.unparsed = unparsed;
Ok(self)
} else {
Err(MyError)
}
}
}
fn main() {
// this is fine:
// let data = "a/b/c/d/e/f/g".to_owned();
// let cf = "/".to_owned();
// let x = First::parse_data(&data, &cf);
// let y = Second::parse_data(&data, &cf);
// this is a problem:
let data = "a/b/c/d/e/f/g".to_owned();
let cf = "/".to_owned();
let x = Everything::new(&data, &cf).set_first();
}