rustwave 0.1.0

A lightweight async event-driven WebSocket framework for Rust
Documentation
use std::fmt::Display;

use serde::{Deserialize, Serialize, de::DeserializeOwned};
use serde_json::Value;

#[derive(Debug, Serialize, Deserialize)]
pub(crate) struct Response<T: Serialize> {
    pub event: String,
    pub data: T,
}

#[derive(Debug, Serialize, Deserialize)]
pub(crate) struct Request {
    pub event: String,
    pub data: Value,
}

/// The data carried by an event, either received from a peer/server or
/// about to be sent.
#[derive(Clone, Debug)]
pub struct Payload {
    data: Value,
}

impl Payload {
    pub(crate) fn new(data: Value) -> Self {
        Self { data }
    }

    /// Deserializes the payload into a concrete type `T`.
    ///
    /// # Errors
    ///
    /// Returns an error if the payload's data doesn't match the shape
    /// expected by `T`.
    ///
    /// # Example
    ///
    /// ```no_run
    /// use rustwave::{Server, Result};
    /// use serde::Deserialize;
    ///
    /// #[derive(Deserialize)]
    /// struct ChatMessage {
    ///     text: String,
    /// }
    ///
    /// #[tokio::main]       
    /// async fn main() -> Result<()> {
    ///     let server = Server::bind("127.0.0.1:8080");
    ///     server.on("message", |data, ctx| async move {
    ///         // parse returns a Result
    ///         if let Ok(message) = data.parse::<ChatMessage>() {
    ///             println!("Client {} say: {}", ctx.get_socket_id(), message.text);
    ///         }
    ///         
    ///     });
    ///     server.run().await?;
    ///     Ok(())
    /// }
    /// ```
    pub fn parse<T: DeserializeOwned>(&self) -> Result<T, serde_json::Error> {
        serde_json::from_value(self.data.clone())
    }

    /// Returns the payload's underlying data as a raw JSON string.
    ///
    /// Useful when you don't need to deserialize into a concrete type, e.g.
    /// for logging or re-broadcasting the data as-is.
    ///
    /// # Example
    ///
    /// ```no_run
    /// use rustwave::{Server, Result};
    ///
    /// #[tokio::main]
    /// async fn main() -> Result<()> {
    ///     let server = Server::bind("127.0.0.1:8080");
    ///
    ///     server.on("message", |data, ctx| async move {
    ///         println!("Client {} say: {}", ctx.get_socket_id(), data.raw());
    ///     });
    ///
    ///     server.run().await?;
    ///
    ///     Ok(())
    /// }
    /// ```
    pub fn raw(&self) -> String {
        self.data.to_string()
    }
}

impl Display for Payload {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.data)
    }
}