I wrote a little module (playground) inspired by owning_ref for safely using raw pointers. The idea is that it's always safe, because the borrow checker won't let the dereferenced values escape the closure. Does this make sense?
mod r {
#[derive(Copy, Clone)]
pub struct OwnedRef<T>{
val: *const T
}
impl<T> std::ops::Deref for OwnedRef<T> {
type Target = T;
fn deref<'a>(&'a self) -> &'a Self::Target {
unsafe {
&*self.val
}
}
}
impl<T> OwnedRef<T> {
pub fn map<'a, U>(&'a self, f: fn(&'a T) -> &'a U) -> OwnedRef<U> {
OwnedRef{ val: &*f(&**self) }
}
}
impl<T> std::fmt::Debug for OwnedRef<T> where T: std::fmt::Debug {
// ...
}
pub struct WithRefs<O, T> {
owner: Box<O>,
data: T,
}
impl<O> WithRefs<O, OwnedRef<O>> {
pub fn new(owner: O) -> Self {
let boxed = Box::into_raw(Box::new(owner));
let reffed = OwnedRef::<O>{val: boxed};
unsafe {
WithRefs{ owner: Box::from_raw(boxed), data: reffed }
}
}
}
impl<O, T> WithRefs<O, T> {
pub fn map<F, U>(self, f: F) -> WithRefs<O, U>
where F: for<'a> FnOnce(&'a T) -> U {
let data1 = f(&self.data);
WithRefs{ owner: self.owner, data: data1 }
}
pub fn with_mut<F>(&mut self, f: F)
where F: for<'a> FnOnce(&'a mut T) {
f(&mut self.data);
}
pub fn with<F>(&self, f: F)
where F: for<'a> FnOnce(&'a T) {
f(&self.data);
}
}
}
// Example
struct Foo{f: f32, b: u32}
pub fn main() {
let a = r::WithRefs::new(5);
let mut b = a.map(|r| vec![*r]);
b.with_mut(|v| v.push(v[0]));
b.with(|v| println!("{:?}", v));
let c = r::WithRefs::new(Foo{ f: 3.0, b: 6 });
let d = c.map(|r| (r.map(|foo| &foo.f), r.map(|foo| &foo.b)));
d.with(|v| println!("{:?}", v));
}