rs-zero 0.1.1

Rust-first microservice framework inspired by go-zero engineering practices
Documentation
use tonic::{Request, Status, service::Interceptor};
use uuid::Uuid;

/// Metadata key propagated by rs-zero RPC clients.
pub const REQUEST_ID_METADATA: &str = "x-request-id";

/// Builds an interceptor that adds a request id when missing.
pub fn request_id_interceptor() -> impl Interceptor {
    |mut request: Request<()>| -> Result<Request<()>, Status> {
        if !request.metadata().contains_key(REQUEST_ID_METADATA) {
            let request_id = Uuid::new_v4().to_string();
            let value = request_id
                .parse()
                .map_err(|_| Status::internal("invalid request id metadata"))?;
            request.metadata_mut().insert(REQUEST_ID_METADATA, value);
        }

        Ok(request)
    }
}

#[cfg(test)]
mod tests {
    use super::{REQUEST_ID_METADATA, request_id_interceptor};
    use tonic::{Request, service::Interceptor};

    #[test]
    fn interceptor_sets_request_id() {
        let mut interceptor = request_id_interceptor();
        let request = interceptor.call(Request::new(())).expect("request");

        assert!(request.metadata().contains_key(REQUEST_ID_METADATA));
    }
}