Skip to content

support for struct-like variants? #5

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

Closed
colin-kiegel opened this issue Dec 19, 2015 · 6 comments
Closed

support for struct-like variants? #5

colin-kiegel opened this issue Dec 19, 2015 · 6 comments

Comments

@colin-kiegel
Copy link
Contributor

This is a great library. 👍

One thing I am missing is struct-like variants:

quick_error! {
    #[derive(Debug)]
    pub enum IoWrapper {
        IoAt(place: &'static str, err: io::Error) {}
    }
}

let err = IoWrapper::IoAt {
    place: unimplemented!(),
    err: unimplemented!()
}  // compile error: `IoWrapper::IoAt` does not name a structure 

Support for struct-like variants would be great AND it would help migrating some existing error definitions to quick-error.

I just checked: std-lib uses struct-like variants for some error enums too:

  • std::str::Utf8Error
  • std::sync::PoisonError
  • std::string::FromUtf8Error

So there seem to be use cases to use both kind of variants. Is it generally possible to implement at all? If so, the syntax could be curly-braces IoAt{place: ..} {} instead of round-braces IoAt(place: ..) {}.

@tailhook
Copy link
Owner

While the syntax is slightly ambiguous ( Variant { display(...) } is a singleton variant with a body), still I think this is possible. It's on my to-do list, but I'm not sure when I can find some time to implement it.

@colin-kiegel
Copy link
Contributor Author

Yes this is true. You could remove this ambiguity by changing the syntax to something like Variant => { display(...) } - i.e. introducing => inbetween. This would feel quite rusty to me, but it would be a breaking change. :-/

@colin-kiegel
Copy link
Contributor Author

As a preparation I merged the enum [] and items [] buffer into one buffer in #9.

    (SORT [enum $name:ident $(#[$meta:meta])* ]
        items [ $( $(#[$imeta:imeta])*
                  => $iitem:ident $(( $($ivar:ident : $ityp:ty),* ))*
                                { $($ifuncs:tt)* } )* ]
  // ...

I now see two options:
(A)

    (SORT [enum $name:ident $(#[$meta:meta])* ]
        struct_items [ $( $(#[$imeta:imeta])*
                  => $iitem:ident $(( $($ivar:ident : $ityp:ty),* ))*
                                { $($ifuncs:tt)* } )* ]
        tuple_items [ $( $(#[$imeta:imeta])*
                  => $iitem:ident $({ $($ivar:ident : $ityp:ty),* })+
                                { $($ifuncs:tt)* } )* ]
  // ...

(B)

    (SORT [enum $name:ident $(#[$meta:meta])* ]
        items [ $( $(#[$imeta:imeta])*
                  => $iitem:ident $(( $($tuple_var:ident : $tuple_typ:ty),* ))*
                                  $({ $($struct_var:ident : $struct_typ:ty),* })*
                                { $($ifuncs:tt)* } )* ]
  // ...

I think (A) is less ambigous - but it has a very verbose signature. How would you approach struct-like-variants?

@tailhook
Copy link
Owner

Well, both are okay for me. Whichever will actually work :) If both work, I would prefer the one which keeps order of items the same. (I guess the one with struct_items/tuple_items may reorder the enum where tuple and struct items are intermixed). If both are, then I don't care much :)

@colin-kiegel
Copy link
Contributor Author

Ok, I will try (C)

    (SORT [$($def:tt)*]
        items [ $( $(#[$imeta:meta])*
                  => $iitem:ident : $imode:tt $(( $($ivar:ident : $ityp:ty),* ))*
                                { $($ifuncs:tt)* } )* ]

where $imode:tt will be either TUPLE or STRUCT. I am confident it will work - but let's see...

@colin-kiegel
Copy link
Contributor Author

thx :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants