Closed xxx closed 1 year ago
As far as I can see, I can't safely give access to the inside of the cell for Debug without also having access to the owner, and the Debug trait doesn't allow that to be passed through. There might be a mutable reference to the contents of the cell active somewhere else, and if the Debug implementation is given an immutable reference, that's a soundness hole according to Rust's ownership rules. That would obviously be called out as a bug in the crate.
I think the only way to do a debugging dump would be if you had access to the owner, and manually access the cell's contents to debug them (e.g. using ro
).
If you can see another way of doing this soundly, let me know, but right now I can't see a way.
Thanks for answering. Yeah, I can't really think of anything either. Right now I'm using this module and wrapping the object temporarily when needed, which takes care of things well enough for me. (In this, key == owner. I think of QCells as more like jail cells, and you need the key to get anything out of it - owner
has another semantic meaning on the project.)
use std::fmt::{Debug, Display, Formatter};
use qcell::QCellOwner;
pub struct WithKey<'a, T> {
pub value: &'a T,
pub cell_key: &'a QCellOwner,
}
/// A trait for types that can be paired with a [`QCellOwner`].
pub trait Keyable<'a> {
/// Get a pairing of me and the cell key.
fn with_key(&'a self, cell_key: &'a QCellOwner) -> WithKey<'a, Self>
where
Self: Sized,
{
WithKey {
value: self,
cell_key,
}
}
/// Key-aware `Debug`
fn keyable_debug(&self, cell_key: &QCellOwner) -> String;
/// Key-aware `Display`
fn keyable_display(&self, cell_key: &QCellOwner) -> String {
self.keyable_debug(cell_key)
}
}
impl<'a, T> Display for WithKey<'a, T>
where
T: Keyable<'a>,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.value.keyable_display(self.cell_key))
}
}
impl<'a, T> Debug for WithKey<'a, T>
where
T: Keyable<'a>,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.value.keyable_debug(self.cell_key))
}
}
impl<'a, T> PartialEq for WithKey<'a, T>
where
T: Keyable<'a> + PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}
Heya, thanks for making this crate.
I'm currently porting a project over from
RefCell
, and I'm finding that I really miss being able to deriveDebug
on things that now contain QCells. Debugging anything in a QCell is requiring me to go in with a debugger every time, when I often just want to dump out what's in it. I typically can't useget_mut
orinto_inner
in any of these places.Do you have any suggestions to make this more ergonomic?