1use reqwest::{header, Client as HttpClient};
2use url::Url;
3
4use crate::{auth::TokenProvider, Error};
5
6const DEFAULT_BASE: &str = "https://api.linkedin.com";
7
8pub struct Client<TP: TokenProvider> {
10 http: HttpClient,
11 base: Url,
12 token_provider: TP,
13 user_agent: String,
14}
15
16impl<TP: TokenProvider> Client<TP> {
17 pub fn new(token_provider: TP) -> Result<Self, Error> {
19 let http = HttpClient::builder().build()?;
20 let base = Url::parse(DEFAULT_BASE).map_err(|e| Error::Config(e.to_string()))?;
21 Ok(Self {
22 http,
23 base,
24 token_provider,
25 user_agent: format!("gen-linkedin/{}", env!("CARGO_PKG_VERSION")),
26 })
27 }
28
29 #[must_use]
31 pub fn with_base(mut self, base: Url) -> Self {
32 self.base = base;
33 self
34 }
35
36 pub fn bearer(&self) -> Result<String, Error> {
38 self.token_provider.bearer_token()
39 }
40
41 pub fn http(&self) -> &HttpClient {
43 &self.http
44 }
45
46 pub fn base(&self) -> &Url {
48 &self.base
49 }
50
51 pub fn user_agent(&self) -> &str {
53 &self.user_agent
54 }
55
56 pub(crate) fn auth_headers(&self) -> Result<header::HeaderMap, Error> {
57 let mut headers = header::HeaderMap::new();
58 headers.insert(
59 header::AUTHORIZATION,
60 format!("Bearer {}", self.bearer()?).parse().unwrap(),
61 );
62 headers.insert(header::USER_AGENT, self.user_agent.parse().unwrap());
63 Ok(headers)
64 }
65}