#Can I define a trait that requires exactly one of its functions to be overridden?

19 messages · Page 1 of 1 (latest)

main hazel
#

I would like to write a trait that requires overriding exactly one of its functions. Overriding zero or more than one fns should be a compile error.

impl OnChange<const KEY: &'static str> {
    fn on_change(raw: &str);
    /// basically does `self.on_change(|raw| f(parse_bool(raw)))`
    fn on_bool_change(val: bool);
    /// same for bool
    fn on_u64_change(val: u64);
}

Also happy to consider other approaches. I am also considering:

  1. Split it out into 3 different traits OnChange OnChangeBool, OnChangeU64
  2. Add a generic OnChange<const KEY: &'static str, const kind: ValueKind>
serene gyro
#

It is not yet possible, but it will be once @tulip anvil 's feature is stabilized

#

The two approaches you mention would be the usual workarounds

main hazel
#

Ahh, amazing. thank you for confirming. Is there an issue/rfc/pr?

#

👀

serene gyro
#

?eval

#![feature(rustc_attrs)] // currently VERY unstable

#[rustc_must_implement_one_of(on_change, on_bool_change, on_u64_change)]
trait OnChange {
    fn on_change(raw: &str) { Self::on_u64_change(raw.parse().unwrap()) }
    fn on_bool_change(val: bool) { Self::on_u64_change(val as _) }
    fn on_u64_change(val: u64) { Self::on_change(&val.to_string()) }
}
naive valveBOT
#
     Running `target/debug/playground`

()
tulip anvil
#

you can also search prs by rustc_must_implement_one_of

main hazel
#

V exciting, thank you for the info + your work on this 😄

tulip anvil
#

Sadly, it's very far from being stable 😅

#

I wanted to use it on some trait in std, but I've forgot which one

#

Also it's not exactly what you want: the attribute doesn't prohibit overriding more methods

tulip anvil
main hazel
#

It makes sense that it would take awhile, sounds like a pretty fundamental change to how traits behave. I'm not familiar with the GHC thing it's based on, though, so maybe it's actually quite well understood.

#

One alternative might be to implement it as a macro crate. You'd need it on both the declaration and impl sides (like how #[async_trait] works)

#

You probably already considered that, just thinking out loud

tulip anvil
tulip anvil