//! Console channel adapter for testing use async_trait::async_trait; use std::sync::Arc; use tokio::sync::mpsc; use zclaw_types::Result; use crate::{Channel, ChannelConfig, ChannelStatus, IncomingMessage, OutgoingMessage}; /// Console channel adapter (for testing) pub struct ConsoleChannel { config: ChannelConfig, status: Arc>, } impl ConsoleChannel { pub fn new(config: ChannelConfig) -> Self { Self { config, status: Arc::new(tokio::sync::RwLock::new(ChannelStatus::Disconnected)), } } } #[async_trait] impl Channel for ConsoleChannel { fn config(&self) -> &ChannelConfig { &self.config } async fn connect(&self) -> Result<()> { let mut status = self.status.write().await; *status = ChannelStatus::Connected; tracing::info!("Console channel connected"); Ok(()) } async fn disconnect(&self) -> Result<()> { let mut status = self.status.write().await; *status = ChannelStatus::Disconnected; tracing::info!("Console channel disconnected"); Ok(()) } async fn status(&self) -> ChannelStatus { self.status.read().await.clone() } async fn send(&self, message: OutgoingMessage) -> Result { // Print to console for testing let msg_id = format!("console_{}", chrono::Utc::now().timestamp()); match &message.content { crate::MessageContent::Text { text } => { tracing::info!("[Console] To {}: {}", message.conversation_id, text); } _ => { tracing::info!("[Console] To {}: {:?}", message.conversation_id, message.content); } } Ok(msg_id) } async fn receive(&self) -> Result> { let (tx, rx) = mpsc::channel(100); // Console channel doesn't receive messages automatically // Messages would need to be injected via a separate method Ok(rx) } }