Skip to main content

a2a_rs/port/
message_handler.rs

1//! Message handling port definitions
2
3#[cfg(feature = "server")]
4use async_trait::async_trait;
5
6use crate::domain::{A2AError, Message, Task};
7
8/// A trait for handling message processing operations
9pub trait MessageHandler {
10    /// Process a message for a specific task
11    fn process_message(
12        &self,
13        task_id: &str,
14        message: &Message,
15        session_id: Option<&str>,
16    ) -> Result<Task, A2AError>;
17
18    /// Validate a message before processing
19    fn validate_message(&self, message: &Message) -> Result<(), A2AError> {
20        // Default implementation - can be overridden
21        if message.parts.is_empty() {
22            return Err(A2AError::ValidationError {
23                field: "message.parts".to_string(),
24                message: "Message must contain at least one part".to_string(),
25            });
26        }
27        Ok(())
28    }
29
30    /// Transform a message before processing (e.g., for content filtering)
31    fn transform_message(&self, message: Message) -> Result<Message, A2AError> {
32        // Default implementation - pass through unchanged
33        Ok(message)
34    }
35}
36
37#[cfg(feature = "server")]
38#[async_trait]
39/// An async trait for handling message processing operations
40pub trait AsyncMessageHandler: Send + Sync {
41    /// Process a message for a specific task
42    async fn process_message(
43        &self,
44        task_id: &str,
45        message: &Message,
46        session_id: Option<&str>,
47    ) -> Result<Task, A2AError>;
48
49    /// Validate a message before processing
50    async fn validate_message(&self, message: &Message) -> Result<(), A2AError> {
51        // Default implementation - can be overridden
52        if message.parts.is_empty() {
53            return Err(A2AError::ValidationError {
54                field: "message.parts".to_string(),
55                message: "Message must contain at least one part".to_string(),
56            });
57        }
58        Ok(())
59    }
60
61    /// Transform a message before processing (e.g., for content filtering)
62    async fn transform_message(&self, message: Message) -> Result<Message, A2AError> {
63        // Default implementation - pass through unchanged
64        Ok(message)
65    }
66
67    /// Handle message processing with validation and transformation
68    async fn handle_message_flow(
69        &self,
70        task_id: &str,
71        message: Message,
72        session_id: Option<&str>,
73    ) -> Result<Task, A2AError> {
74        // Validate the message
75        self.validate_message(&message).await?;
76
77        // Transform the message if needed
78        let transformed_message = self.transform_message(message).await?;
79
80        // Process the message
81        self.process_message(task_id, &transformed_message, session_id)
82            .await
83    }
84}