In adding a new argument to a function (event_log.publish
, below), I've created a mutable/immutable borrow problem for myself, which I haven't been able to solve.
Based on advice offered on similar questions here and on Stack Overflow, I tried moving the self.event_log
reference out to a variable at the top of the session.publish_to_event_log
function, but that just gets me the same error, this time on the match get_publish_plugin(&self)
line.
How can I restructure my code to avoid this?
use lazycell::LazyCell;
fn get_publish_plugin<'a, 'b>(session : &'a Session) -> Result<Option<&'b Publish>, ()> {
Ok(session.hooks.get(session)?
.events
.as_ref()
.and_then(|events| events.publish.as_ref()))
}
struct EventHooks {
publish : Option<Publish>,
}
struct EventLog {}
impl EventLog {
fn publish(&mut self, _plugin : Option<&Publish>) {
println!("Launch some external command");
}
}
struct HookConfig {
events: Option<EventHooks>,
}
struct LazyHookConfig {
settings: LazyCell<HookConfig>,
}
impl LazyHookConfig {
pub fn get(&self, session : &Session) -> Result<&HookConfig, ()> {
self.settings.try_borrow_with(|| Ok(HookConfig {
events: Some(EventHooks {
publish: Some(Publish {}),
}),
}))
}
}
struct Publish {}
struct Session {
hooks: LazyHookConfig,
event_log : EventLog,
}
impl Session {
fn publish_to_event_log(&mut self) {
match get_publish_plugin(&self) {
Ok(plugin) => {
self.event_log.publish(plugin);
}
Err(_) => {
eprintln!("Some error");
}
}
}
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/lib.rs:4:22
|
4 | Ok(session.hooks.get(session)?
| ^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 3:23...
--> src/lib.rs:3:23
|
3 | fn get_publish_plugin<'a, 'b>(session : &'a Session) -> Result<Option<&'b Publish>, ()> {
| ^^
note: ...so that reference does not outlive borrowed content
--> src/lib.rs:4:8
|
4 | Ok(session.hooks.get(session)?
| ^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 3:27...
--> src/lib.rs:3:27
|
3 | fn get_publish_plugin<'a, 'b>(session : &'a Session) -> Result<Option<&'b Publish>, ()> {
| ^^
= note: ...so that the expression is assignable:
expected std::result::Result<std::option::Option<&'b Publish>, _>
found std::result::Result<std::option::Option<&Publish>, _>
error: aborting due to previous error
For more information about this error, try `rustc --explain E0495`.
error: Could not compile `playground`.
To learn more, run the command again with --verbose.