diff --git a/.github/img/logo-macros.svg b/.github/img/logo-macros.svg new file mode 100644 index 0000000..0cd8060 --- /dev/null +++ b/.github/img/logo-macros.svg @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 67c3f7a..110b315 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ path = "lib/lib.rs" [features] cli-stylize = ["dep:bitflags"] logger = ["dep:log"] +macros = [] [dependencies] bitflags = { version = "2.5.0", optional = true } diff --git a/README.md b/README.md index c5acd8f..5fe6edf 100644 --- a/README.md +++ b/README.md @@ -14,4 +14,5 @@ # Features - [x] [cli/stylize](lib/cli/stylize) -- [x] [logging](lib/logger) \ No newline at end of file +- [x] [logging](lib/logger) +- [x] [macros](lib/macros) \ No newline at end of file diff --git a/examples/fail_macro.rs b/examples/fail_macro.rs new file mode 100644 index 0000000..9371acd --- /dev/null +++ b/examples/fail_macro.rs @@ -0,0 +1,18 @@ +use { + eyre::{set_hook, DefaultHandler, Result}, + lool::f, +}; + +fn setup_eyre() { + let _ = set_hook(Box::new(DefaultHandler::default_with)); +} + +fn main() -> Result<()> { + setup_eyre(); + + if (2 + 2) == 5 { + return f!("Oh no! I'm bad at math!"); + } + + Ok(()) +} diff --git a/lib/lib.rs b/lib/lib.rs index e7d96d8..8e3eb3b 100644 --- a/lib/lib.rs +++ b/lib/lib.rs @@ -2,3 +2,6 @@ pub mod cli; #[cfg(feature = "logger")] pub mod logger; + +#[cfg(feature = "macros")] +pub mod macros; diff --git a/lib/logger/README.md b/lib/logger/README.md index 582fd81..b76f03c 100644 --- a/lib/logger/README.md +++ b/lib/logger/README.md @@ -16,7 +16,7 @@ This crate is for internal use. It's only published privately. ```bash -cargo add lool --registry=lugit +cargo add lool --registry=lugit --features loggers ``` # Setup diff --git a/lib/macros/README.md b/lib/macros/README.md new file mode 100644 index 0000000..dd1b2e3 --- /dev/null +++ b/lib/macros/README.md @@ -0,0 +1,82 @@ +

+ +
+
+
+ +

lool » macros is a collection of utility macros for rust.

+

+ +
+
+
+ +# Installation + +This crate is for internal use. It's only published privately. + +```bash +cargo add lool --registry=lugit --features macros +``` + +# Macros + +## `s` + +A macro to create a `String` from a `&str`. + +```rs +use lool::s; + +fn main() { + let s = s!("Hello, world!"); + // now `s` is a `String` +} +``` + +## `f` or `fail` + +A macro to use with the [`eyre`](https://crates.io/crates/eyre) crate. +It basically creates an `Err`. + +It's almost the same as `bail!` from the `anyhow` crate, but this one doesn't explicitly returns (the `bail!` macro creates a `return` statement). + +This macro is equivalent to: `Err(eyre!())`. + +```rs +use lool::f; + +fn main() -> eyre::Result<()> { + if (2 + 2) == 5 { + f!("Oh no! I'm bad at math!"); + } + + Ok(()) +} +``` + +which is equivalent to: + +```rs +use eyre::eyre; + +fn main() -> eyre::Result<()> { + if (2 + 2) == 5 { + return Err(eyre!("Oh no! I'm bad at math!")); + } + + Ok(()) +} +``` + +It also works as a final statement: + +```rs +use lool::f; + +fn fail_always() -> eyre::Result<()> { + // no ; at the end + f!("I'm a failure") +} +``` + diff --git a/lib/macros/mod.rs b/lib/macros/mod.rs new file mode 100644 index 0000000..2da6995 --- /dev/null +++ b/lib/macros/mod.rs @@ -0,0 +1,83 @@ +/// 🧉 » create string +/// -- +/// +/// create a new `String` from a string literal or a string expression - +/// this macro is equivalent to `String::from()`. +/// +/// ### Example +/// ```rust +/// use lool::s; +/// let s: String = s!("hello world"); +/// ``` +#[macro_export] +macro_rules! s { + ($s:expr) => { + String::from($s) + }; +} + +/// 🧉 » fail macro +/// -- +/// +/// this macro is equivalent to `Err(eyre!())`. +/// +/// same as `bail!` but without the explicit return +/// +/// ### Example +/// +/// ```should_panic +/// use lool::fail; +/// use eyre::Result; +/// # use eyre::{set_hook, DefaultHandler}; +/// # fn setup_eyre() { +/// # let _ = set_hook(Box::new(DefaultHandler::default_with)); +/// # } +/// +/// fn main() -> Result<()> { +/// # setup_eyre(); +/// fail!("permission denied") +/// } +/// ``` +#[macro_export] +macro_rules! fail { + ($msg:literal $(,)?) => { + Err(eyre::eyre!($msg)) + }; + ($err:expr $(,)?) => { + Err(eyre::eyre!($err)) + }; + ($fmt:expr, $($arg:tt)*) => { + Err(eyre::eyre!($fmt, $($arg)*)) + }; +} + +/// 🧉 » fail macro +/// -- +/// +/// this macro is equivalent to `Err(eyre!())`. +/// +/// same as `bail!` but without the explicit return +/// +/// this is an alias for `fail!` +/// +/// ### Example +/// +/// ```should_panic +/// use lool::f; +/// use eyre::Result; +/// # use eyre::{set_hook, DefaultHandler}; +/// # fn setup_eyre() { +/// # let _ = set_hook(Box::new(DefaultHandler::default_with)); +/// # } +/// +/// fn main() -> Result<()> { +/// # setup_eyre(); +/// f!("permission denied") +/// } +/// ``` +#[macro_export] +macro_rules! f { + ($($tokens:tt)*) => { + lool::fail!($($tokens)*) + }; +}