From 6659920446bf065be7b2b4958bf256920713fda0 Mon Sep 17 00:00:00 2001 From: Kanji Tanaka Date: Thu, 2 Mar 2023 09:53:58 +0900 Subject: [PATCH 1/3] Up patch version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 1a43a3a..0d6a6ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "slack-messaging" -version = "0.2.1" +version = "0.2.2" authors = ["kaicoh "] edition = "2021" keywords = ["slack", "messaging", "webhook"] From ee5722db5982e2ebdd947dc0207ac75b671e1133 Mon Sep 17 00:00:00 2001 From: Kanji Tanaka Date: Thu, 2 Mar 2023 14:45:44 +0900 Subject: [PATCH 2/3] Add mrkdwn and plain_text macros --- src/blocks/elements/text.rs | 98 +++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 + src/macros.rs | 90 ++++++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 src/macros.rs diff --git a/src/blocks/elements/text.rs b/src/blocks/elements/text.rs index 25e9fde..a4dd371 100644 --- a/src/blocks/elements/text.rs +++ b/src/blocks/elements/text.rs @@ -6,6 +6,42 @@ const TYPE_MRKDWN: &str = "mrkdwn"; /// [Text object](https://api.slack.com/reference/block-kit/composition-objects#text) /// representation. /// +/// # Example +/// +/// ## type plain_text +/// +/// ``` +/// use slack_messaging::blocks::elements::Text; +/// use serde_json::json; +/// +/// let text = Text::plain("Hello, World!"); +/// let text_json = serde_json::to_value(text).unwrap(); +/// +/// let expected = json!({ +/// "type": "plain_text", +/// "text": "Hello, World!", +/// "emoji": true +/// }); +/// +/// assert_eq!(text_json, expected); +/// ``` +/// +/// ## type mrkdwn +/// +/// ``` +/// use slack_messaging::blocks::elements::Text; +/// use serde_json::json; +/// +/// let text = Text::mrkdwn("Hello, World!"); +/// let text_json = serde_json::to_value(text).unwrap(); +/// +/// let expected = json!({ +/// "type": "mrkdwn", +/// "text": "Hello, World!", +/// }); +/// +/// assert_eq!(text_json, expected); +/// ``` #[derive(Debug, Clone, Serialize)] pub struct Text { #[serde(rename = "type")] @@ -149,3 +185,65 @@ impl Text { } } } + +impl PartialEq for Text { + fn eq(&self, other: &Self) -> bool { + if self.kind != other.kind || self.text.as_str() != other.text.as_str() { + return false; + } + + match self.kind { + TYPE_PLAIN => self.emoji.unwrap_or(false) == other.emoji.unwrap_or(false), + TYPE_MRKDWN => self.verbatim.unwrap_or(false) == other.verbatim.unwrap_or(false), + _ => false, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_equals_with_same_type_and_text() { + let plain_0 = Text::plain("Hello"); + let plain_1 = Text::plain("Hello"); + + let mrkdwn_0 = Text::mrkdwn("Hello"); + let mrkdwn_1 = Text::mrkdwn("Hello"); + + assert_eq!(plain_0, plain_1); + assert_eq!(mrkdwn_0, mrkdwn_1); + + assert_ne!(plain_0, mrkdwn_0); + assert_ne!(plain_0, mrkdwn_1); + assert_ne!(plain_1, mrkdwn_0); + assert_ne!(plain_1, mrkdwn_1); + } + + #[test] + fn it_compares_emoji_field_when_plain_text() { + let plain_0 = Text::plain("Hello").set_emoji(false); + let plain_1 = Text::plain("Hello"); + + assert_ne!(plain_0, plain_1); + + let plain_0 = Text::plain("Hello").set_emoji(false); + let plain_1 = Text::plain("Hello").set_emoji(false); + + assert_eq!(plain_0, plain_1); + } + + #[test] + fn it_compares_verbatim_field_when_mrkdwn() { + let mrkdwn_0 = Text::mrkdwn("Hello").set_verbatim(true); + let mrkdwn_1 = Text::mrkdwn("Hello"); + + assert_ne!(mrkdwn_0, mrkdwn_1); + + let mrkdwn_0 = Text::mrkdwn("Hello").set_verbatim(true); + let mrkdwn_1 = Text::mrkdwn("Hello").set_verbatim(true); + + assert_eq!(mrkdwn_0, mrkdwn_1); + } +} diff --git a/src/lib.rs b/src/lib.rs index 017e271..64831bc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -111,6 +111,8 @@ pub mod blocks; /// Format text for slack app. Require `fmt` feature. #[cfg(feature = "fmt")] pub mod fmt; +#[macro_use] +mod macros; mod message; pub use attachment::Attachment; diff --git a/src/macros.rs b/src/macros.rs new file mode 100644 index 0000000..8fad179 --- /dev/null +++ b/src/macros.rs @@ -0,0 +1,90 @@ +/// Constructs `plain_text` [Text](crate::blocks::elements::Text). +/// +/// ``` +/// use slack_messaging::plain_text; +/// use slack_messaging::blocks::elements::Text; +/// +/// let text = plain_text!("Hello, World!"); +/// let expected = Text::plain("Hello, World!"); +/// +/// assert_eq!(text, expected); +/// +/// let greet = "Hi"; +/// let name = "Tanaka"; +/// +/// // You can use this like format! macro. +/// let text = plain_text!("{}, {}!", greet, name); +/// let expected = Text::plain("Hi, Tanaka!"); +/// +/// assert_eq!(text, expected); +/// ``` +#[macro_export] +macro_rules! plain_text { + ($fmt:expr) => { + $crate::blocks::elements::Text::plain(format!($fmt)) + }; + ($fmt:expr, $($arg:tt)+) => { + $crate::blocks::elements::Text::plain(format!($fmt, $($arg)+)) + }; +} + +/// Constructs `mrkdwn` [Text](crate::blocks::elements::Text). +/// +/// ``` +/// use slack_messaging::mrkdwn; +/// use slack_messaging::blocks::elements::Text; +/// +/// let text = mrkdwn!("Hello, World!"); +/// let expected = Text::mrkdwn("Hello, World!"); +/// +/// assert_eq!(text, expected); +/// +/// let greet = "Hi"; +/// let name = "Tanaka"; +/// +/// // You can use this like format! macro. +/// let text = mrkdwn!("{}, {}!", greet, name); +/// let expected = Text::mrkdwn("Hi, Tanaka!"); +/// +/// assert_eq!(text, expected); +/// ``` +#[macro_export] +macro_rules! mrkdwn { + ($fmt:expr) => { + $crate::blocks::elements::Text::mrkdwn(format!($fmt)) + }; + ($fmt:expr, $($arg:tt)+) => { + $crate::blocks::elements::Text::mrkdwn(format!($fmt, $($arg)+)) + }; +} + +#[cfg(test)] +mod tests { + use crate::blocks::elements::Text; + + #[test] + fn it_works_macro_plain_text_given_expression() { + let text = plain_text!("Hello, Tanaka!"); + assert_eq!(text, Text::plain("Hello, Tanaka!")); + } + + #[test] + fn it_works_macro_plain_text_given_expression_and_tokens() { + let name = "Tanaka"; + let text = plain_text!("Hello, {}!", name); + assert_eq!(text, Text::plain("Hello, Tanaka!")); + } + + #[test] + fn it_works_macro_mrkdwn_given_expression() { + let text = mrkdwn!("Hello, Tanaka!"); + assert_eq!(text, Text::mrkdwn("Hello, Tanaka!")); + } + + #[test] + fn it_works_macro_mrkdwn_given_expression_and_tokens() { + let name = "Tanaka"; + let text = mrkdwn!("Hello, {}!", name); + assert_eq!(text, Text::mrkdwn("Hello, Tanaka!")); + } +} From 0cd8ff65bf0b642efbf16baa192a1e35ef41e3cf Mon Sep 17 00:00:00 2001 From: Kanji Tanaka Date: Thu, 2 Mar 2023 14:59:32 +0900 Subject: [PATCH 3/3] Add changelog for macros feature --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a412144..4659c54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [0.2.2][] - 2023-03-02 + +- https://github.com/kaicoh/slack-messaging/pull/6 Add `mrkdwn` and `plain_text` macros. + ## [0.2.1][] - 2023-02-28 - https://github.com/kaicoh/slack-messaging/pull/4 Extend Message to be an interaction response. @@ -12,6 +16,7 @@ - pre-release +[0.2.2]: https://github.com/kaicoh/slack-messaging/releases/v0.2.2 [0.2.1]: https://github.com/kaicoh/slack-messaging/releases/v0.2.1 [0.2.0]: https://github.com/kaicoh/slack-messaging/releases/v0.2.0 [0.1.0]: https://github.com/kaicoh/slack-messaging/releases/v0.1.0