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

All components implement the Default trait now in Rust #6458

Merged
merged 11 commits into from
May 30, 2024

Conversation

Wumpf
Copy link
Member

@Wumpf Wumpf commented May 30, 2024

What

While working on ComponentFallbackProvider for highly customized & context dependent fallback value generation (which can be used by ui, views and visualizer alike to ensure they all see the same data in the case of absent data) I noticed that:

  • many fallback values are trivial and only occasionally need custom / heuristical fallbacks
  • having some guarantee on a "rock bottom" fallback can simplify a lot of code (i.e. the ability to treat lack of fallback as an error)

In order to get this "bottom fallback" @jleibs and me decided after some back and forth to simply implement the Default trait for all component types. This is enforced by a new generated method, list_default_components which is part of re_viewer and will be in a follow-up pr used to populate a "component fallback registry".


Alternatives considered: Originally I used this construct to distinguish Default from potentially non-sensical fallbacks. But I eventually discarded this as too overenginered:

/// Provides a fallback value for a component type.
///
/// If this type also implements `Default`, the default value is used.
/// However, even component types without a logical default always provide a fallback value.
/// For example there is no meaningful default for `Position`, but it still comes with a fallback value.
///
/// Whether to implement `Default` or `ComponentFallback` is a per component design decision.
/// Prefer `Default` whenever there is an intuitive default value for all situations, prefer `ComponentFallback` otherwise.
///
/// The fallback value is used as the initial value when creating overrides or defaults in the viewer's UI.
/// It can also be used by visualizers itself in order to sync their fallbacks with the ui.
///
/// Note that the Rerun Viewer may employ more complex fallback heuristics by implementing a `ComponentFallbackProvider`.
pub trait ComponentFallback {
    fn fallback() -> Self;
}

/// [`ComponentFallback`] implementation for types that implement `Default`.
impl<T: Default + Loggable> ComponentFallback for T {
    fn fallback() -> Self {
        Default::default()
    }
}

Checklist

  • I have read and agree to Contributor Guide and the Code of Conduct
  • I've included a screenshot or gif (if applicable)
  • I have tested the web demo (if applicable):
  • The PR title and labels are set such as to maximize their usefulness for the next release's CHANGELOG
  • If applicable, add a new check to the release checklist!

To run all checks from main, comment on the PR with @rerun-bot full-check.

@Wumpf Wumpf changed the title All components implement the Default now in Rust All components implement the Default trait now in Rust May 30, 2024
Copy link
Member

@emilk emilk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense! But we should be careful when picking the defaults, and err on the side of explicit

@Wumpf Wumpf merged commit c7dbfdf into main May 30, 2024
34 checks passed
@Wumpf Wumpf deleted the andreas/defaults-for-all-components branch May 30, 2024 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants