summaryrefslogtreecommitdiffstats
path: root/third_party/rust/error-support-macros
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/rust/error-support-macros
parentInitial commit. (diff)
downloadfirefox-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.json1
-rw-r--r--third_party/rust/error-support-macros/Cargo.toml32
-rw-r--r--third_party/rust/error-support-macros/src/lib.rs109
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",
+ ))
+ }
+}