FromMessage

Trait FromMessage 

Source
pub trait FromMessage: Sized {
    // Required method
    fn from_message<'life0, 'life1, 'life2, 'life3, 'async_trait>(
        message: &'life0 Message,
        conn: &'life1 Connection,
        state: &'life2 AppState,
        extensions: &'life3 Extensions,
    ) -> Pin<Box<dyn Future<Output = Result<Self>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait;
}
Expand description

Trait for types that can be extracted from WebSocket messages and context.

This trait is the core of the extractor system. Types that implement FromMessage can be used as handler parameters, and the framework will automatically extract and validate the data before calling the handler.

§Implementation Guidelines

When implementing custom extractors:

  1. Be specific: Return clear error messages when extraction fails
  2. Be efficient: Avoid expensive operations if possible
  3. Be safe: Validate all extracted data
  4. Document: Explain what data is extracted and any requirements

§Examples

§Simple Extractor

use wsforge::prelude::*;
use async_trait::async_trait;

struct MessageLength(usize);

#[async_trait]
impl FromMessage for MessageLength {
    async fn from_message(
        message: &Message,
        _conn: &Connection,
        _state: &AppState,
        _extensions: &Extensions,
    ) -> Result<Self> {
        let len = message.as_bytes().len();
        Ok(MessageLength(len))
    }
}

async fn handler(MessageLength(len): MessageLength) -> Result<String> {
    Ok(format!("Message length: {}", len))
}

§Extractor with Validation

use wsforge::prelude::*;
use async_trait::async_trait;

struct ValidatedText(String);

#[async_trait]
impl FromMessage for ValidatedText {
    async fn from_message(
        message: &Message,
        _conn: &Connection,
        _state: &AppState,
        _extensions: &Extensions,
    ) -> Result<Self> {
        let text = message.as_text()
            .ok_or_else(|| Error::extractor("Message must be text"))?;

        if text.is_empty() {
            return Err(Error::extractor("Text cannot be empty"));
        }

        if text.len() > 1000 {
            return Err(Error::extractor("Text too long (max 1000 characters)"));
        }

        Ok(ValidatedText(text.to_string()))
    }
}

Required Methods§

Source

fn from_message<'life0, 'life1, 'life2, 'life3, 'async_trait>( message: &'life0 Message, conn: &'life1 Connection, state: &'life2 AppState, extensions: &'life3 Extensions, ) -> Pin<Box<dyn Future<Output = Result<Self>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Extracts Self from the message and context.

§Arguments
  • message - The WebSocket message being processed
  • conn - The connection that sent the message
  • state - The application state
  • extensions - Request-scoped extension data
§Errors

Returns an error if extraction fails. Common reasons include:

  • Required data is missing
  • Data format is invalid
  • Type mismatch
  • Validation failure

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl FromMessage for Connection

Extractor for the active connection.

Provides access to the connection that sent the message, allowing you to:

  • Get the connection ID
  • Access connection metadata
  • Send messages back to the specific client

§Examples

§Sending Response
use wsforge::prelude::*;

async fn handler(msg: Message, conn: Connection) -> Result<()> {
    conn.send_text("Message received!")?;
    Ok(())
}
§Using Connection Info
use wsforge::prelude::*;

async fn handler(conn: Connection) -> Result<String> {
    let info = conn.info();
    Ok(format!("Client from {} connected at {}",
        info.addr, info.connected_at))
}
Source§

impl FromMessage for Message

Extractor for the raw message.

Use this when you need access to the complete message without automatic deserialization.

§Examples

§Raw Message Processing
use wsforge::prelude::*;

async fn handler(msg: Message) -> Result<String> {
    if msg.is_text() {
        Ok(format!("Text: {}", msg.as_text().unwrap()))
    } else if msg.is_binary() {
        Ok(format!("Binary: {} bytes", msg.as_bytes().len()))
    } else {
        Ok("Unknown message type".to_string())
    }
}
Source§

impl FromMessage for ConnectInfo

Source§

impl FromMessage for Data

Source§

impl<T: Send + Sync + 'static> FromMessage for State<T>

Source§

impl<T: Send + Sync + Clone + 'static> FromMessage for Extension<T>

Source§

impl<T: DeserializeOwned + Send + Sync + Clone + 'static> FromMessage for Path<T>

Source§

impl<T: DeserializeOwned + Send + Sync + Clone + 'static> FromMessage for Query<T>

Source§

impl<T: DeserializeOwned + Send> FromMessage for Json<T>