use crate::extract::FromContext;
use std::cell::RefCell;
use std::convert::Infallible;
use std::rc::Rc;
const PDK_AGENT: &str = "PDK-HttpClient";
const PDK_VERSION: &str = env!("CARGO_PKG_VERSION");
thread_local! {
static USER_AGENT: RefCell<Option<Rc<UserAgent>>> = const { RefCell::new(None) };
}
impl<C> FromContext<C> for Rc<UserAgent> {
type Error = Infallible;
fn from_context(_context: &C) -> Result<Self, Self::Error> {
let agent = USER_AGENT
.with(|cell| cell.borrow().clone())
.unwrap_or_default();
Ok(Rc::clone(&agent))
}
}
pub fn set_user_agent(user_agent: UserAgent) {
USER_AGENT.with(|cell| cell.replace(Some(Rc::new(user_agent))));
}
pub struct UserAgent {
value: String,
}
impl Default for UserAgent {
fn default() -> Self {
UserAgent::new(PDK_AGENT, PDK_VERSION)
}
}
impl UserAgent {
pub fn new(key: &str, version: &str) -> Self {
UserAgent {
value: format!("{key}/{version}"),
}
}
pub fn value(&self) -> &str {
self.value.as_str()
}
}
#[cfg(test)]
mod test {
use crate::user_agent::UserAgent;
#[test]
fn default() {
assert_eq!(
UserAgent::default().value(),
&format!("PDK-HttpClient/{}", env!("CARGO_PKG_VERSION"))
);
}
}