tap_node/message/
router.rs

1//! Message routing implementation.
2//!
3//! This module provides message routing capabilities for the TAP Node.
4
5use log::debug;
6use std::sync::Arc;
7use tap_msg::didcomm::Message;
8
9use crate::agent::AgentRegistry;
10use crate::error::{Error, Result};
11use crate::message::MessageRouter;
12
13/// Default implementation of MessageRouter
14#[derive(Debug, Clone)]
15pub struct DefaultMessageRouter {
16    /// Registry of agents
17    agents: Option<Arc<AgentRegistry>>,
18}
19
20impl Default for DefaultMessageRouter {
21    fn default() -> Self {
22        Self::new()
23    }
24}
25
26impl DefaultMessageRouter {
27    /// Create a new default message router
28    pub fn new() -> Self {
29        Self { agents: None }
30    }
31
32    /// Set the agent registry
33    pub fn with_agents(mut self, agents: Arc<AgentRegistry>) -> Self {
34        self.agents = Some(agents);
35        self
36    }
37}
38
39impl MessageRouter for DefaultMessageRouter {
40    fn route_message_impl(&self, message: &Message) -> Result<String> {
41        // Check if the message has a "to" field
42        if let Some(to) = &message.to {
43            if !to.is_empty() {
44                // Check if the first to DID exists in our registry
45                let to_did = to[0].clone();
46
47                // If we have an agent registry, check if the agent exists
48                if let Some(agents) = &self.agents {
49                    if agents.has_agent(&to_did) {
50                        debug!("Routing message to: {}", to_did);
51                        return Ok(to_did);
52                    }
53                } else {
54                    // If we don't have an agent registry, just return the first DID
55                    debug!("No agent registry available, routing to: {}", to_did);
56                    return Ok(to_did);
57                }
58            }
59        }
60
61        // If we get here, we couldn't route the message
62        Err(Error::Dispatch(format!(
63            "No route found for message: {}",
64            message.id
65        )))
66    }
67}
68
69/// Composite message router that can delegate to multiple routers
70#[derive(Debug, Default)]
71pub struct CompositeMessageRouter {
72    /// The routers to use, in order
73    routers: Vec<crate::message::MessageRouterType>,
74}
75
76impl CompositeMessageRouter {
77    /// Create a new composite router
78    pub fn new() -> Self {
79        Self::default()
80    }
81
82    /// Add a router to the chain
83    pub fn add_router(&mut self, router: crate::message::MessageRouterType) {
84        self.routers.push(router);
85    }
86}
87
88impl MessageRouter for CompositeMessageRouter {
89    fn route_message_impl(&self, message: &Message) -> Result<String> {
90        // Try each router in sequence
91        for router in &self.routers {
92            match router {
93                crate::message::MessageRouterType::Default(r) => {
94                    match r.route_message_impl(message) {
95                        Ok(target) => return Ok(target),
96                        Err(_) => continue, // Try the next router
97                    }
98                } // Add other router types here if needed
99            }
100        }
101
102        // If we get here, no router could handle the message
103        Err(Error::Dispatch(format!(
104            "No route found for message: {}",
105            message.id
106        )))
107    }
108}