war-pigeon 0.1.0

An ergonomic Rust client for War Pigeon, the runtime message delivery system.
Documentation
use crate::Error;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use tracing::error;

#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(tag = "type", content = "data")]
pub enum Message {
    Custom(Value),

    #[cfg(feature = "discord")]
    Discord(Box<crate::messages::discord::DiscordMessage>),
}
impl Message {
    /// Deliver a [`Message`] with War Pigeon.
    ///
    /// NOTE: We recommend using [`crate::Client::deliver()`] to send a [`Message`]
    /// over this method, as this will initiate a new HTTP client for every call.
    pub async fn deliver(self) -> Result<(), Error> {
        let http_client = reqwest::Client::new();
        Self::send(self, &http_client).await
    }

    /// Send the [`Message`] to the War Pigeon API.
    pub(crate) async fn send(self, http_client: &reqwest::Client) -> Result<(), Error> {
        let json_payload = serde_json::to_string(&self)
            .inspect_err(|e| error!("failed to parse `Message` into json string: {e}"))?;

        http_client
            .post("https://war-pigeon.byte-forge.io/message")
            .header("Content-type", "application/json")
            .body(json_payload)
            .send()
            .await?
            .error_for_status()?;

        Ok(())
    }

    pub fn into_json(self) -> Result<String, Error> {
        let json_data = match self {
            Message::Custom(v) => serde_json::to_string(&v),

            #[cfg(feature = "discord")]
            Message::Discord(msg) => serde_json::to_string(&msg),
        }?;

        Ok(json_data)
    }
}