A safe interface to project through shared references to core::cell::Cell.
Documentation: https://docs.rs/cell-project
use std::cell::Cell;use cell_project::cell_project as cp;// renamed for ergonomicsstructPoint{x:f32,y:f32,}fnget_x_cell(point:&Cell<Point>) -> &Cell<f32>{cp!(Point, point.x)}The syntax for the macro is as follows
let projection = cp!($TypeOfValue, $value_identifier.$field_identifier);You may not pass an expression for $value_identifier, if you need to then you should do.
let value = Cell::new(get_point());let projection = cp!(Point, value.y);If you need to project through multiple fields then you need to call cp! multiple times, once per projection
structPair<T>(T,T);// let some_pair: &Cell<Pair<Point>>;let point = cp!(Pair<Point>, some_pair.0);let x = cp!(Point, point.x);note: for generic types, you can use _ to infer the generic parameters
fnget_x_cell<T>(point:&Cell<Pair<T>>) -> &Cell<T>{cp!(Pair<_>, point.0)}Some limitations, you cannot project an enum variant because that is potentially unsound.
let x = Cell::new(Some(0));// let's imagine a macro like `try_cell_project`, which takes a varaint as well as a typelet proj = cell_project::try_cell_project!(Option<_>,Some, x.0).unwrap();
x.set(None);// we can still write to the `Cell` directly// this will read uninitialized memory (because that's what `None` wrote in)// and there is no way to fix this. Enums cannot allow safe projection through// a shared mutable reference (like `&Cell<_>`)let _ = proj.get();so you cannot project through enums
Another limitation of stable, you can only project to Sized types. For example, if I have a type
structUnsized(i32,[u8]);Then I can only project to the first field, because the second field is !Sized
nightly - unlocks cell_project::nightly_cell_project, which uses the unstable #![feature(raw_ref_op)] to
allow projections to !Sized fields.
License: MIT