use std::str::FromStr;
use tonic::metadata::{MetadataKey, MetadataMap, MetadataValue};
use tonic::service::interceptor::InterceptedService;
use tonic::service::Interceptor;
use tonic::{Request, Status};
use super::otel::{inject_context, Injector};
#[derive(Clone)]
pub struct GrpcOtelInterceptor;
pub type GrpcOtelInterceptedService<Svc> = InterceptedService<Svc, GrpcOtelInterceptor>;
impl Interceptor for GrpcOtelInterceptor {
fn call(&mut self, mut request: Request<()>) -> Result<Request<()>, Status> {
inject_context(&mut MetadataMapInjector(request.metadata_mut()));
Ok(request)
}
}
pub struct MetadataMapInjector<'h>(&'h mut MetadataMap);
impl Injector for MetadataMapInjector<'_> {
fn set(&mut self, key: &str, value: String) {
let key_value = MetadataKey::from_str(key)
.ok()
.and_then(|key| Some((key, MetadataValue::from_str(&value).ok()?)));
if let Some((key, value)) = key_value {
self.0.insert(key, value);
}
}
}