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:
- Be specific: Return clear error messages when extraction fails
- Be efficient: Avoid expensive operations if possible
- Be safe: Validate all extracted data
- 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§
Sourcefn 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,
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 processedconn- The connection that sent the messagestate- The application stateextensions- 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§
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))
}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())
}
}