use std::sync::Mutex;
static LAST_CORR: Mutex<Option<String>> = Mutex::new(None);
const HEADER: &str = "x-request-id";
pub fn record_corr(result: &Result<reqwest::Response, reqwest::Error>) {
match result {
Ok(resp) => record_corr_response(resp),
Err(_) => {
if let Ok(mut slot) = LAST_CORR.lock() {
*slot = None;
}
}
}
}
pub fn record_corr_response(resp: &reqwest::Response) {
if let Some(id) = resp.headers().get(HEADER).and_then(|h| h.to_str().ok()) {
if let Ok(mut slot) = LAST_CORR.lock() {
*slot = Some(id.to_string());
}
}
}
pub fn take_last_corr() -> Option<String> {
LAST_CORR.lock().ok().and_then(|mut slot| slot.take())
}
#[cfg(test)]
mod tests {
use super::*;
fn response_with(id: Option<&str>) -> reqwest::Response {
let mut builder = http::Response::builder().status(200);
if let Some(id) = id {
builder = builder.header(HEADER, id);
}
reqwest::Response::from(builder.body("{}").unwrap())
}
#[test]
fn capture_take_missing_header_and_transport_error() {
let _ = take_last_corr();
record_corr(&Ok(response_with(Some("req-123"))));
assert_eq!(take_last_corr().as_deref(), Some("req-123"));
assert_eq!(take_last_corr(), None);
record_corr(&Ok(response_with(Some("req-xyz"))));
record_corr(&Ok(response_with(None)));
assert_eq!(take_last_corr().as_deref(), Some("req-xyz"));
let err = reqwest::Response::from(http::Response::builder().status(500).body("").unwrap())
.error_for_status();
assert!(err.is_err());
record_corr(&err);
assert_eq!(take_last_corr(), None);
}
}