use std::{any::Any, time::Duration}; use rmcp::task_manager::{ OperationDescriptor, OperationMessage, OperationProcessor, OperationResultTransport, }; struct DummyTransport { id: String, value: u32, } impl OperationResultTransport for DummyTransport { fn operation_id(&self) -> &String { &self.id } fn as_any(&self) -> &dyn Any { self } } #[tokio::test] async fn executes_enqueued_future() { let mut processor = OperationProcessor::new(); let descriptor = OperationDescriptor::new("op1", "dummy"); let future = Box::pin(async { tokio::time::sleep(Duration::from_millis(10)).await; Ok(Box::new(DummyTransport { id: "op1".to_string(), value: 42, }) as Box) }); processor .submit_operation(OperationMessage::new(descriptor, future)) .expect("submit operation"); tokio::time::sleep(Duration::from_millis(30)).await; let results = processor.peek_completed(); assert_eq!(results.len(), 1); let payload = results[0] .result .as_ref() .unwrap() .as_any() .downcast_ref::() .unwrap(); assert_eq!(payload.value, 42); } #[tokio::test] async fn rejects_duplicate_operation_ids() { let mut processor = OperationProcessor::new(); let descriptor = OperationDescriptor::new("dup", "dummy"); let future = Box::pin(async { Ok(Box::new(DummyTransport { id: "dup".to_string(), value: 1, }) as Box) }); processor .submit_operation(OperationMessage::new(descriptor, future)) .expect("first submit"); let descriptor_dup = OperationDescriptor::new("dup", "dummy"); let future_dup = Box::pin(async { Ok(Box::new(DummyTransport { id: "dup".to_string(), value: 2, }) as Box) }); let err = processor .submit_operation(OperationMessage::new(descriptor_dup, future_dup)) .expect_err("duplicate should fail"); assert!(format!("{err}").contains("already running")); }