Reputation: 3
I have problems with my code in rust. Ofc it has to to with borrowing. This is my first try at own code after reading the rust book.
The thing is, I kinda understand what the problem is and have an idea how to solve it, but that solution would end in some ugly structured code.
I have a struct which implements following method:
pub(crate) fn get_calendar_events(&self, name: &str) -> Result<Vec<Calendar>,String> {
let xml: String = self.get_calendar_xml(name).map_err(|e|{
format!("Error extracting xml: {}", e)
})?;
let event_responses: Vec<Responses> = self.parse_event_responses(&xml);
let mut events: Vec<Calendar> = Vec::new();
for response in event_responses {
let ics_result: Result<Response,Error> = self.webdav_client.get(&format!("{}/{}", self.url, response.href));
let ics_response: Response = ics_result.map_err(|e|{
format!("Error in ics result: {}", e)
})?;
let mut ics: String = ics_response.text().map_err(|e|{
format!("Error in ics response: {}", e)
})?;
let calendar_result: Result<Calendar<'_>, String> = read_calendar(&ics);
let calendar_event: Calendar = calendar_result.map_err(|e|{
format!("Error reading calendar event: {}", e)
})?;
events.push(calendar_event);
}
Ok(events)
}
Inside the loop I have the variable ics
. The method read_calendar
is from the crate "iCalendar" and takes a &str
as argument. I want unpack the result from read-calendar
and push the calendar_event
in a Vec which I want the method to return.
I get the error, that ics
will be dropped at the end of the loop and calendar_result
(and calendar_event
) can't reference that value when it is dropped.
The only idea I have to solve this error is to outsource the complete loop to the place where I need access to the calendar_event
, but this will end up in some chaotic looking code.
Coming from java I probably approach things too much in that typical object-oriented way and have to try to rethink my approach.
Upvotes: 0
Views: 82
Reputation: 393
It looks to me like the issue is that the Calendar
struct doesn't take ownership of the input string, it just keeps the reference.
I'm not super familiar with the icalendar
library, but it looks like there are two different Calendar
structs: icalendar::parser::Calendar<'a>, and icalendar::Calendar.
I did some tweaking on my machine to remove the webdav stuff so it would build, but it seems that using the icalendar::Calendar
variant will compile:
use icalendar::{parser::read_calendar, Calendar as CalendarOwned};
pub fn get_calendar_events(name: &str) -> Result<Vec<CalendarOwned>, String> {
let mut events: Vec<CalendarOwned> = Vec::new();
loop {
let mut ics: String = "thing".to_owned();
let calendar_result = read_calendar(&ics);
let calendar_event = calendar_result
.map_err(|e| format!("Error reading calendar event: {}", e))
.unwrap();
events.push(calendar_event.into());
break;
}
Ok(events)
}
This version of the struct looks to be mostly similar, but taking ownership of its component parts instead of borrowing them. Like I say though, i'm not familliar with this library so I could be talking rubbish.
Upvotes: 4