[pve-devel] [PATCH v3 proxmox 02/66] notify: preparation for the first endpoint plugin
Wolfgang Bumiller
w.bumiller at proxmox.com
Tue Jul 18 12:13:15 CEST 2023
Not an in-depth review, just an explanation:
On Tue, Jul 18, 2023 at 09:19:54AM +0200, Lukas Wagner wrote:
> Thanks for the review!
>
> On 7/17/23 17:48, Maximiliano Sandoval wrote:
> >
> > Lukas Wagner <l.wagner at proxmox.com> writes:
> >
(...)
> > > +#[derive(Debug)]
> > > +pub enum Error {
> > > + ConfigSerialization(Box<dyn StdError + Send + Sync + 'static>),
FYI you can leave out the `'static` in type definitions like this. It's
the only possible choice and therefor automatic ;-)
^ Here we have `Box<dyn StdError>`
...
> > > + ConfigDeserialization(Box<dyn StdError + Send + Sync + 'static>),
> > > + NotifyFailed(String, Box<dyn StdError + Send + Sync + 'static>),
> > > + TargetDoesNotExist(String),
> > > +}
> > > +
> > > +impl Display for Error {
> > > + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
> > > + match self {
> > > + Error::ConfigSerialization(err) => {
> > > + write!(f, "could not serialize configuration: {err}")
> > > + }
> > > + Error::ConfigDeserialization(err) => {
> > > + write!(f, "could not deserialize configuration: {err}")
> > > + }
> > > + Error::NotifyFailed(endpoint, err) => {
> > > + write!(f, "could not notify via endpoint(s): {endpoint}: {err}")
> > > + }
> > > + Error::TargetDoesNotExist(target) => {
> > > + write!(f, "notification target '{target}' does not exist")
> > > + }
> > > + }
> > > + }
> > > +}
> > > +
> > > +impl StdError for Error {
> > > + fn source(&self) -> Option<&(dyn StdError + 'static)> {
> > > + match self {
^ Here, `self` is `&Self`
> > > + Error::ConfigSerialization(err) => Some(&**err),
> >
> > Does this really need the double deref?
>
> Yeah, does not seem to work any way. Though I'm not sure I can fully explain why.
> Copied the approach from (I think) the TFA crate.
Since, as noted above, `self` is `&Self`, `err` here will be `&T`.
`T` is `Box<dyn StdError + Send + Sync>`.
So we have `&Box<dyn StdError + Send + Sync>`
The first deref goes to `Box<dyn StdError + Send + Sync>` via an immutable ref.
We cannot return this as this would be a moving expression and rust does
not implicitly dereference multiple times automatically.
The second deref calls `<Box as Deref>::deref` and implicitly
dereferences it (since 'Deref' is kind of "transparent" to the '*'
operator), from `&(dyn StdError + Send + Sync)` to `(dyn StdError + Send
+ Sync)`.
Finally we borrow -> `&**` :-)
More information about the pve-devel
mailing list