I'm implementing a web service using tonic grpc crate. Here is the my code:
use std::cell::RefCell;
use std::ops::{Deref, DerefMut};
use std::sync::Mutex;
fn main() {
let my_struct = MyStruct {data_ref: RefCell::new(None), data: vec![MyData(28)]};
my_struct.my_fun();
// my_struct.my_fun_is_gone(); This is not working.
println!("{}", my_struct.data_ref.borrow().deref().unwrap().0);
}
/// AUTO GENERATED CODE OR THIRD PARTY TRAITS
///for example tonic generated Grpc services
trait TonicGeneratedGrpcService {
fn my_fun_is_gone(&self); //so I Can't change the &self lifetime parameter
}
struct MyData(u8);
struct MyStruct<'a> {
data: Vec<MyData>, //this struct is owns this property, there is no any problem
data_ref: RefCell<Option<&'a MyData>>, //And sometimes I want to save the data
}
impl<'a> TonicGeneratedGrpcService for MyStruct<'a> {
fn my_fun_is_gone(&self) { //I can't change the &self lifetime parameter because this is just an implementation of some super traits, change the lifetime parameters also requires change the super trait's method's lifetime.
//***********COMPILER ERROR is occurred HERE, how can I make this working?*************
let some_of_data = &self.data[0]; //Maybe &self.data[1], &self.data[2]...
*self.data_ref.borrow_mut() = Some(some_of_data);
}
}
impl<'a> MyStruct<'a> {
//Below code is works fine if this is myself defined method, but I can't change the lifetime of "self" in super traits if this is a implementation of tonic generated service or other third party traits
fn my_fun(&'a self) {
let some_of_data = &self.data[0]; //Maybe &self.data[1], &self.data[2]...
*self.data_ref.borrow_mut() = Some(some_of_data);
}
}
My final purpose is save the reference that one of the Vec<MyData>
into data_ref field at runtime by some conditions.
Here is the compiler error:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:28:29
|
28 | let some_of_data = &self.data[0]; //Maybe &self.data[1], &self.data[2]...
| ^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime defined here...
--> src/main.rs:26:23
|
26 | fn my_fun_is_gone(&self) { //I can't change the &self lifetime parameter because this is just an implementation of some super traits,...
| ^^^^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:28:29
|
28 | let some_of_data = &self.data[0]; //Maybe &self.data[1], &self.data[2]...
| ^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined here...
--> src/main.rs:25:6
|
25 | impl<'a> TonicGeneratedGrpcService for MyStruct<'a> {
| ^^
note: ...so that the expression is assignable
--> src/main.rs:29:39
|
29 | *self.data_ref.borrow_mut() = Some(some_of_data);
| ^^^^^^^^^^^^^^^^^^
= note: expected `Option<&'a MyData>`
found `Option<&MyData>`
I can't change the source code of TonicGeneratedGrpcService
trait because it may be in the third party crate or auto generated code,
and now I cannot find any way to make work the my_fun_is_gone
method implementation.
Should I avoid the lifetime and use reference counted pointers (Rc
, Arc
) rather then save reference (&MyData
) directly in struct MyStruct
?
Or there any way to make work this?