Skip to content

Commit

Permalink
feat: Better error messages for span! macro (#43)
Browse files Browse the repository at this point in the history
With this PR, if a user accidentally uses `,` as a separator when the
first argument is a style, they'll will get a better compiler error
message:

<img width="748" alt="image"
src="https://github.com/ratatui-org/ratatui-macros/assets/1813121/58ec025c-56c8-4a4a-998f-7a48a6b327fd">

This also updates the docstrings to reiterate that `,` must be used for
format specifier and `;` must be used for style.
  • Loading branch information
kdheepak committed May 13, 2024
1 parent 204307f commit c50b01d
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 4 deletions.
49 changes: 46 additions & 3 deletions src/span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,61 @@
/// let span = span!(style; "test {:04}", 123);
/// ```
///
/// # Note
///
/// The first parameter must be a formatting specifier followed by a comma OR
/// anything that can be converted into a [`Style`] followed by a semicolon.
///
/// For example, the following will fail to compile:
///
/// ```compile_fail
/// # use ratatui::prelude::*;
/// # use ratatui_macros::span;
/// let span = span!(Modifier::BOLD, "hello world");
/// ```
///
/// But this will work:
///
/// ```rust
/// # use ratatui::prelude::*;
/// # use ratatui_macros::span;
/// let span = span!(Modifier::BOLD; "hello world");
/// ```
///
/// The following will fail to compile:
///
/// ```compile_fail
/// # use ratatui::prelude::*;
/// # use ratatui_macros::span;
/// let span = span!("hello", "world");
/// ```
///
/// But this will work:
///
/// ```rust
/// # use ratatui::prelude::*;
/// # use ratatui_macros::span;
/// let span = span!("hello {}", "world");
/// ```
///
/// [`Color`]: crate::style::Color
/// [`Style`]: crate::style::Style
/// [`Span`]: crate::text::Span
/// [`Style`]: crate::style::Style
#[macro_export]
macro_rules! span {
($string:literal) => {
ratatui::text::Span::raw(format!($string))
};
($string:literal, $($arg:tt)*) => {
ratatui::text::Span::raw(format!($string, $($arg)*))
};
($style:expr, $($arg:tt)*) => {
compile_error!("first parameter must be a formatting specifier followed by a comma OR a `Style` followed by a semicolon")
};
($style:expr; $($arg:tt)*) => {
ratatui::text::Span::styled(format!($($arg)*), $style)
};
($($arg:tt)*) => {
ratatui::text::Span::raw(format!($($arg)*))
};
}

#[cfg(test)]
Expand Down
6 changes: 5 additions & 1 deletion tests/ui/fails.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use ratatui::prelude::*;
use ratatui_macros::constraints;
use ratatui_macros::{constraints, span};

fn main() {
constraints![,];
Expand All @@ -13,4 +13,8 @@ fn main() {
assert_eq!(b, Constraint::Length(2));

let [a, b, c] = constraints![ == 1, == 10%, == 2; 4];

let _ = span!(Modifier::BOLD, "hello world");

let _ = span!("hello", "hello world");
}
16 changes: 16 additions & 0 deletions tests/ui/fails.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,22 @@ note: while trying to match `%`
| (== $token:tt %) => {
| ^

error: first parameter must be a formatting specifier followed by a comma OR a `Style` followed by a semicolon
--> tests/ui/fails.rs:17:13
|
17 | let _ = span!(Modifier::BOLD, "hello world");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `span` (in Nightly builds, run with -Z macro-backtrace for more info)

error: argument never used
--> tests/ui/fails.rs:19:28
|
19 | let _ = span!("hello", "hello world");
| ------- ^^^^^^^^^^^^^ argument never used
| |
| formatting specifier missing

error[E0527]: pattern requires 2 elements but array has 3
--> tests/ui/fails.rs:8:9
|
Expand Down

0 comments on commit c50b01d

Please sign in to comment.