Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refuses to serialize Rc<RefCell<Item>> field - despite #[serde(skip_serializing)] #2510

Closed
cambiata opened this issue Jul 15, 2023 · 4 comments

Comments

@cambiata
Copy link

When using the "rc" feature flag, serializing structs with Vec<Rc<Child>> fields works fine.

However, if I add a field to the same struct that shouldn't be serialized (using #[serde(skip_serializing)] for that) containing a RefCell (for example a Rc<RefCell<Child>>), it doesn't compile.

#[derive(Debug, PartialEq, Eq, Hash, serde::Deserialize, serde::Serialize)]
struct Child {
    data: i32,
}

#[derive(Debug, PartialEq, Eq, Hash, serde::Deserialize, serde::Serialize)]
struct Parent {
    // persistent field - should be serialized
    children: Vec<Rc<Child>>,

    // computed field - shouldn't be serialized
    // As soon as I add the child field below
    #[serde(skip_serializing)]
    child: Rc<RefCell<Child>>, // <- causes compile error `RefCell<Child>: Hash` not satisified
}

Is there a way to allow non-serialized fields containing RefCells in an otherwise serialized struct?
@jonasbb
Copy link
Contributor

jonasbb commented Jul 15, 2023

That is a problem with the Hash derive macro, that ships with the Rust standard library. It has nothing to do with serde.
These derive macros offer no customization. You will need to implement Hash by hand or look for a crate.

@Mingun
Copy link
Contributor

Mingun commented Jul 15, 2023

The problem is because RefCell does not implement Hash. A possible workaround is to use newtype wrapper for Rc<RefCell<Child>> and implement Hash for it manually. But I recommend to google first, why RefCell doesn't implement Hash for the first place -- maybe there is some non-obvious obstacles

@dtolnay dtolnay closed this as completed Jul 15, 2023
@cambiata
Copy link
Author

Thanks guys! I get that RefCell doesn't implement Hash, but - as mentioned - I don't need to serialize any field using RefCells.
When adding #[serde(skip_serializing)] to a field, I was expecting that field to be completely ignored - regardless using RefCell or not.

It would be very nice if the serde docs could provide some info about this limitation, and - at best - some examples on how to get around it.

@dtolnay
Copy link
Member

dtolnay commented Jul 16, 2023

I am locking the issue because, as already pointed out above, this has literally nothing to do with serde.

You can remove all serde attributes and derives from this code and still get the same error.

@serde-rs serde-rs locked and limited conversation to collaborators Jul 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

4 participants