use facet::Facet;
use crate::ServiceRegistry;
#[derive(Clone, Debug, Facet)]
pub struct ServiceInfo {
pub name: String,
pub doc: String,
pub methods: Vec<MethodInfo>,
}
#[derive(Clone, Debug, Facet)]
pub struct MethodInfo {
pub id: u32,
pub name: String,
pub full_name: String,
pub doc: String,
pub args: Vec<ArgInfo>,
pub is_streaming: bool,
}
#[derive(Clone, Debug, Facet)]
pub struct ArgInfo {
pub name: String,
pub type_name: String,
}
#[derive(Clone, Debug, Default)]
pub struct DefaultServiceIntrospection;
impl DefaultServiceIntrospection {
pub fn new() -> Self {
Self
}
pub fn list_services(&self) -> Vec<ServiceInfo> {
ServiceRegistry::with_global(|registry| {
registry
.iter_services()
.map(|service| ServiceInfo {
name: service.name.to_string(),
doc: service.doc.clone(),
methods: service
.iter_methods()
.map(|method| MethodInfo {
id: method.id.0,
name: method.name.to_string(),
full_name: method.full_name.clone(),
doc: method.doc.clone(),
args: method
.args
.iter()
.map(|arg| ArgInfo {
name: arg.name.to_string(),
type_name: arg.type_name.to_string(),
})
.collect(),
is_streaming: method.is_streaming,
})
.collect(),
})
.collect()
})
}
pub fn describe_service(&self, name: &str) -> Option<ServiceInfo> {
self.list_services().into_iter().find(|s| s.name == name)
}
pub fn has_method(&self, method_id: u32) -> bool {
ServiceRegistry::with_global(|registry| {
registry.method_by_id(crate::MethodId(method_id)).is_some()
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_introspection_empty() {
let introspection = DefaultServiceIntrospection::new();
let services = introspection.list_services();
let _ = services;
}
#[test]
fn test_describe_service() {
let introspection = DefaultServiceIntrospection::new();
let result = introspection.describe_service("NonExistentService12345");
assert!(result.is_none() || result.is_some()); }
#[test]
fn test_has_method() {
let introspection = DefaultServiceIntrospection::new();
let has_control = introspection.has_method(0);
let _ = has_control;
}
}