Skip to content

add #[serde(default)] to Node (and, perhaps other similar structs) #18883

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

CupOfTeaJay
Copy link
Contributor

Objective

Many structs that implement Serialize and Deserialize (when Bevy's serialize feature is enabled) also implement Default, but do not apply the #[serde(default)] attribute. This requires those who want to deserialize said structs to explicitly specify all struct fields in their data-interchange format, even if they all end up being their default values.

For example, I am trying to implement a plugin that allows me to specify a UI tree in JSON files. I noticed that when I tried to deserialize the Node component (which has 39 fields!) with serde, I was met with an error that in essence would have required me to specify all fields of Node in the JSON file, of which I was only using non-default values for:

  • height
  • width
  • border
  • flex_direction

Solution

  1. Apply #[serde(default)] to the Node struct
  2. If '1' is reasonable, perhaps start a conversation about applying this attribute to all structs that implement Serialize, Deserialize, and Default ?

After applying this attribute on a local fork of Bevy, I was able to deserialize my UI tree exactly as intended with minimal markup in my JSON files.

There might be a reason not to do this that I am not aware of, I tried looking for similar past issues but could not find much conversation about #[serde(default)]. Documentation on this attribute can be found here.

#[serde(default = "path")]

When deserializing, any missing fields should be filled in from the object returned by the given function or method. The function must be callable as fn() -> T. For example default = "my_default" would invoke my_default() and default = "SomeTrait::some_default" would invoke SomeTrait::some_default(). Only allowed on structs.

Testing

I did not write any formal tests for this. Informally, I simply added #[serde(default)] to Node to a local fork of Bevy and successfully deserialized an instance of Node with default values not specified in my JSON file.

Sample JSON

Note how I only needed to specify 4/39 fields for Node. Upon deserialization, serde invoked Node::default() to populate the missing fields.

{
    "UiRoot": {
        "Node": {
            "height": {"Percent": 100.0},
            "width": {"Percent": 100.0},
            "border": {"left": {"Px": 5.0}, "right": {"Px": 5.0}, "top": {"Px": 5.0}, "bottom": {"Px": 5.0}},
            "flex_direction": "Row"
        },
        "BorderColor": {"Srgba": {"red": 1.0, "green": 0.0, "blue": 0.0, "alpha": 1.0}},
        "Children": ["CreateGameButton"]
    },
    "CreateGameButton": {
        "Node": {
            "height": {"Percent": 25.0},
            "width": {"Percent": 25.0},
            "border": {"left": {"Px": 5.0}, "right": {"Px": 5.0}, "top": {"Px": 5.0}, "bottom": {"Px": 5.0}},
            "flex_direction": "Row"
        },
        "BorderColor": {"Srgba": {"red": 0.0, "green": 1.0, "blue": 0.0, "alpha": 1.0}},
        "Interaction": "None"
    }
}

@Henauxg
Copy link
Contributor

Henauxg commented Apr 20, 2025

EDIT possible alternatives:

@Henauxg Henauxg added C-Feature A new feature, making something new possible A-UI Graphical user interfaces, styles, layouts, and widgets A-Cross-Cutting Impacts the entire engine labels Apr 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Cross-Cutting Impacts the entire engine A-UI Graphical user interfaces, styles, layouts, and widgets C-Feature A new feature, making something new possible
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants