diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /third_party/rust/error-support-macros | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/error-support-macros')
-rw-r--r-- | third_party/rust/error-support-macros/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | third_party/rust/error-support-macros/Cargo.toml | 32 | ||||
-rw-r--r-- | third_party/rust/error-support-macros/src/lib.rs | 109 |
3 files changed, 142 insertions, 0 deletions
diff --git a/third_party/rust/error-support-macros/.cargo-checksum.json b/third_party/rust/error-support-macros/.cargo-checksum.json new file mode 100644 index 0000000000..65c2ea5e04 --- /dev/null +++ b/third_party/rust/error-support-macros/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"7143b51f48478384002380c7d6a5a071c7e985b1fc86cf2c74d4e738ba41b541","src/lib.rs":"67740f320fb8012c7df017ed2ad5ebe130940a3bb73d42e0445b31b39f844d79"},"package":null}
\ No newline at end of file diff --git a/third_party/rust/error-support-macros/Cargo.toml b/third_party/rust/error-support-macros/Cargo.toml new file mode 100644 index 0000000000..4d194ddc60 --- /dev/null +++ b/third_party/rust/error-support-macros/Cargo.toml @@ -0,0 +1,32 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2021" +name = "error-support-macros" +version = "0.1.0" +publish = false +license = "MPL-2.0" + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1.0" +quote = "1.0" + +[dependencies.syn] +version = "2.0" +features = [ + "derive", + "parsing", + "full", +] diff --git a/third_party/rust/error-support-macros/src/lib.rs b/third_party/rust/error-support-macros/src/lib.rs new file mode 100644 index 0000000000..4746d44127 --- /dev/null +++ b/third_party/rust/error-support-macros/src/lib.rs @@ -0,0 +1,109 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_quote, spanned::Spanned}; + +const ERR_MSG: &str = "Expected #[handle_error(path::to::Error)]"; + +/// A procedural macro that exposes internal errors to external errors the +/// consuming applications should handle. It requires that the internal error +/// implements [`error_support::ErrorHandling`]. +/// +/// Additionally, this procedural macro has side effects, including: +/// * It would log the error based on a pre-defined log level. The log level is defined +/// in the [`error_support::ErrorHandling`] implementation. +/// * It would report some errors using an external error reporter, in practice, this +/// is implemented using Sentry in the app. +/// +/// # Example +/// ```ignore +/// use error_support::{handle_error, GetErrorHandling, ErrorHandling}; +/// use std::fmt::Display +///#[derive(Debug, thiserror::Error)] +/// struct Error {} +/// type Result<T, E = Error> = std::result::Result<T, E>; + +/// impl Display for Error { +/// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +/// write!(f, "Internal Error!") +/// } +/// } +/// +/// #[derive(Debug, thiserror::Error)] +/// struct ExternalError {} +/// +/// impl Display for ExternalError { +/// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +/// write!(f, "External Error!") +/// } +/// } +/// +/// impl GetErrorHandling for Error { +/// type ExternalError = ExternalError; +/// +/// fn get_error_handling(&self) -> ErrorHandling<Self::ExternalError> { +/// ErrorHandling::convert(ExternalError {}) +/// } +/// } +/// +/// // The `handle_error` macro maps from the error supplied in the mandatory argument +/// // (ie, `Error` in this example) to the error returned by the function (`ExternalError` +/// // in this example) +/// #[handle_error(Error)] +/// fn do_something() -> std::result::Result<String, ExternalError> { +/// Err(Error{}) +/// } +/// +/// // The error here is an `ExternalError` +/// let _: ExternalError = do_something().unwrap_err(); +/// ``` +#[proc_macro_attribute] +pub fn handle_error(args: TokenStream, input: TokenStream) -> TokenStream { + let mut err_path = None; + let parser = syn::meta::parser(|meta| { + if meta.input.is_empty() && err_path.replace(meta.path).is_none() { + Ok(()) + } else { + Err(syn::Error::new(meta.input.span(), ERR_MSG)) + } + }); + TokenStream::from( + match syn::parse::Parser::parse(parser, args) + .map_err(|e| syn::Error::new(e.span(), ERR_MSG)) + .and_then(|()| syn::parse::<syn::Item>(input)) + .and_then(|parsed| impl_handle_error(&parsed, err_path.unwrap())) + { + Ok(res) => res, + Err(e) => e.to_compile_error(), + }, + ) +} + +fn impl_handle_error( + input: &syn::Item, + err_path: syn::Path, +) -> syn::Result<proc_macro2::TokenStream> { + if let syn::Item::Fn(item_fn) = input { + let original_body = &item_fn.block; + + let mut new_fn = item_fn.clone(); + new_fn.block = parse_quote! { + { + (|| -> ::std::result::Result<_, #err_path> { + #original_body + })().map_err(::error_support::convert_log_report_error) + } + }; + + Ok(quote! { + #new_fn + }) + } else { + Err(syn::Error::new( + input.span(), + "#[handle_error(..)] can only be used on functions", + )) + } +} |