use std::sync::Arc;
use crate::invoker::Invoker;
pub trait Handler: Invoker {
fn service_id(&self) -> &'static str;
fn method_ids(&self) -> &'static [&'static str];
}
pub type BoxHandler = Box<dyn Handler>;
pub type ArcHandler = Arc<dyn Handler>;
#[cfg(test)]
mod tests {
use super::*;
use crate::error::{Error, Result};
use crate::stream::{Context, Stream};
use async_trait::async_trait;
struct TestHandler;
#[async_trait]
impl Invoker for TestHandler {
async fn invoke_method(
&self,
_service_id: &str,
method_id: &str,
_stream: Box<dyn Stream>,
) -> (bool, Result<()>) {
match method_id {
"Method1" | "Method2" => (true, Ok(())),
_ => (false, Err(Error::Unimplemented)),
}
}
}
impl Handler for TestHandler {
fn service_id(&self) -> &'static str {
"test.Service"
}
fn method_ids(&self) -> &'static [&'static str] {
&["Method1", "Method2"]
}
}
#[test]
fn test_handler_metadata() {
let handler = TestHandler;
assert_eq!(handler.service_id(), "test.Service");
assert_eq!(handler.method_ids(), &["Method1", "Method2"]);
}
#[test]
fn test_arc_handler() {
let handler: ArcHandler = Arc::new(TestHandler);
assert_eq!(handler.service_id(), "test.Service");
assert_eq!(handler.method_ids(), &["Method1", "Method2"]);
}
struct MockStream;
#[async_trait]
impl Stream for MockStream {
fn context(&self) -> &Context {
static CTX: std::sync::OnceLock<Context> = std::sync::OnceLock::new();
CTX.get_or_init(Context::new)
}
async fn send_bytes(&self, _data: bytes::Bytes) -> Result<()> {
Ok(())
}
async fn recv_bytes(&self) -> Result<bytes::Bytes> {
Err(Error::StreamClosed)
}
async fn close_send(&self) -> Result<()> {
Ok(())
}
async fn close(&self) -> Result<()> {
Ok(())
}
}
#[tokio::test]
async fn test_handler_invoke() {
let handler: ArcHandler = Arc::new(TestHandler);
let (found, result) = handler
.invoke_method("test.Service", "Method1", Box::new(MockStream))
.await;
assert!(found);
assert!(result.is_ok());
let (found, result) = handler
.invoke_method("test.Service", "Unknown", Box::new(MockStream))
.await;
assert!(!found);
assert!(result.is_err());
}
}