diff --git a/Cargo.toml b/Cargo.toml index 6cbd276..befc911 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,7 @@ uuid = { version = "0.8.1", optional = true } diesel = { version = "1.4.4", features = ["postgres"] } futures-executor = "0.3.4" paste = "0.1.12" +thiserror = "1.0.18" trybuild = "1.0.26" [features] diff --git a/derive/src/resource_error.rs b/derive/src/resource_error.rs index cf9040d..032151b 100644 --- a/derive/src/resource_error.rs +++ b/derive/src/resource_error.rs @@ -167,7 +167,7 @@ impl ErrorVariant }) } - fn into_match_arm(self, krate : &TokenStream, enum_ident : &Ident) -> TokenStream + fn into_match_arm(self, krate : &TokenStream, enum_ident : &Ident) -> Result { let ident = &self.ident; let fields_pat = self.fields_pat(); @@ -185,21 +185,23 @@ impl ErrorVariant }); // the response will come directly from the from_ty if present - let res = match self.from_ty { - Some((from_index, _)) => { + let res = match (self.from_ty, status) { + (Some((from_index, _)), None) => { let from_field = &self.fields[from_index].ident; quote!(#from_field.into_response_error()) }, - None => quote!(Ok(#krate::Response { + (Some(_), Some(_)) => return Err(Error::new(ident.span(), "When #[from] is used, #[status] must not be used!")), + (None, Some(status)) => quote!(Ok(#krate::Response { status: { #status }.into(), body: #krate::gotham::hyper::Body::empty(), mime: None - })) + })), + (None, None) => return Err(Error::new(ident.span(), "Missing #[status(code)] for this variant")) }; - quote! { + Ok(quote! { #enum_ident::#ident #fields_pat => #res - } + }) } fn were(&self) -> Option @@ -293,7 +295,9 @@ pub fn expand_resource_error(input : DeriveInput) -> Result } let were = variants.iter().filter_map(|variant| variant.were()).collect::>(); - let variants = variants.into_iter().map(|variant| variant.into_match_arm(&krate, &ident)); + let variants = variants.into_iter() + .map(|variant| variant.into_match_arm(&krate, &ident)) + .collect_to_result()?; Ok(quote! { #display_impl diff --git a/src/result/auth_result.rs b/src/result/auth_result.rs index bc3f84f..10f0183 100644 --- a/src/result/auth_result.rs +++ b/src/result/auth_result.rs @@ -62,8 +62,9 @@ pub enum AuthErrorOrOther #[status(FORBIDDEN)] #[display("Forbidden")] Forbidden, + #[status(INTERNAL_SERVER_ERROR)] #[display("{0}")] - Other(#[from] E) + Other(E) } impl From for AuthErrorOrOther @@ -76,6 +77,17 @@ impl From for AuthErrorOrOther } } +impl From for AuthErrorOrOther +where + // TODO https://gitlab.com/msrd0/gotham-restful/-/issues/20 + F : std::error::Error + Into +{ + fn from(err : F) -> Self + { + Self::Other(err.into()) + } +} + /** This return type can be used to map another `ResourceResult` that can only be returned if the client is authenticated. Otherwise, an empty _403 Forbidden_ response will be issued. Use can