diff --git a/.github/workflows/basic.yml b/.github/workflows/basic.yml index fdbed61b..27b70b05 100644 --- a/.github/workflows/basic.yml +++ b/.github/workflows/basic.yml @@ -11,6 +11,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: + features: ['', '--all-features'] rust: - stable - beta @@ -25,15 +26,17 @@ jobs: - name: Cache uses: Swatinem/rust-cache@v2 + with: + prefix-key: ${{ matrix.features }} - name: Build all targets - run: cargo build --all-targets + run: cargo build --all-targets ${{ matrix.features }} - name: Run the test suite - run: cargo test + run: cargo test ${{ matrix.features }} - name: Check formatting run: cargo fmt --check - name: Check clippy lints - run: cargo clippy -- -D warnings + run: cargo clippy ${{ matrix.features }} -- -D warnings diff --git a/Cargo.toml b/Cargo.toml index 0c95262a..4223befc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,9 +9,13 @@ repository = "https://github.com/frostly/rust-slack" edition = "2018" rust-version = "1.67.1" +[features] +# Enables use of the synchronous "blocking" Client +blocking = ["reqwest/blocking"] + [dependencies] chrono = "0.4.39" -reqwest = { version = "0.12.12", features = ["blocking", "json"] } +reqwest = { version = "0.12.12", features = ["json"] } hex = "0.4.3" serde = { version = "1.0.217", features = ["derive"] } serde_json = "1.0.135" @@ -20,3 +24,7 @@ url = { version = "2.5.4", features = ["serde"] } [dev-dependencies] insta = { version = "1.42.0", features = ["json"] } + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/README.md b/README.md index 29060c73..7d749b37 100644 --- a/README.md +++ b/README.md @@ -12,18 +12,22 @@ A rust crate for sending messages to Slack via webhooks. Upgrading? See the [CHANGELOG](./CHANGELOG.md). +# Features + +- **blocking**: Provides a synchronous "blocking" slack client + # Usage Simply run this to add it to your `Cargo.toml`: ```console -cargo add slack-hook +cargo add slack-hook --features=blocking ``` and then start sending messages! ```rust,no_run -use slack_hook::{Slack, PayloadBuilder}; +use slack_hook::{blocking::Slack, PayloadBuilder}; fn main() { let slack = Slack::new("https://hooks.slack.com/services/abc/123/45z").unwrap(); diff --git a/src/blocking.rs b/src/blocking.rs new file mode 100644 index 00000000..dabb45ca --- /dev/null +++ b/src/blocking.rs @@ -0,0 +1,31 @@ +use crate::{Error, Payload, Result}; + +use reqwest::{blocking::Client, Url}; + +/// Handles sending messages to slack +#[derive(Debug, Clone)] +pub struct Slack { + hook: Url, + client: Client, +} + +impl Slack { + /// Construct a new instance of slack for a specific incoming url endpoint. + pub fn new(hook: T) -> Result { + Ok(Slack { + hook: hook.into_url()?, + client: Client::new(), + }) + } + + /// Send payload to slack service + pub fn send(&self, payload: &Payload) -> Result<()> { + let response = self.client.post(self.hook.clone()).json(payload).send()?; + + if response.status().is_success() { + Ok(()) + } else { + Err(Error::Slack(format!("HTTP error {}", response.status()))) + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 2a2fdf05..9b475a34 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,13 +11,14 @@ unused_results, rust_2018_idioms )] +#![cfg_attr(docsrs, feature(doc_cfg))] //! Library to send messages to slack rooms //! supports entire messaging API, including attachments and fields //! also support for built-in colors as well as any hex colors // Run doctests on the README -#[doc = include_str!("../README.md")] +#[cfg_attr(feature = "blocking", doc = include_str!("../README.md"))] #[cfg(doctest)] pub struct ReadmeDoctests; @@ -32,6 +33,10 @@ pub use crate::slack::{Slack, SlackLink, SlackText, SlackTextContent, SlackTime, mod macros; mod attachment; +/// A blocking slack client +#[cfg(feature = "blocking")] +#[cfg_attr(docsrs, doc(cfg(feature = "blocking")))] +pub mod blocking; mod error; mod hex; mod payload; diff --git a/src/slack.rs b/src/slack.rs index 44018281..d9c4c5e0 100644 --- a/src/slack.rs +++ b/src/slack.rs @@ -1,6 +1,6 @@ use crate::{Error, Payload, Result}; use chrono::NaiveDateTime; -use reqwest::{blocking::Client, Url}; +use reqwest::{Client, Url}; use serde::{Serialize, Serializer}; use std::fmt; @@ -21,8 +21,13 @@ impl Slack { } /// Send payload to slack service - pub fn send(&self, payload: &Payload) -> Result<()> { - let response = self.client.post(self.hook.clone()).json(payload).send()?; + pub async fn send(&self, payload: &Payload) -> Result<()> { + let response = self + .client + .post(self.hook.clone()) + .json(payload) + .send() + .await?; if response.status().is_success() { Ok(())