url_cleaner_engine/glue/
proxy.rs1use std::str::FromStr;
4
5use serde::{Serialize, Deserialize};
6use url::Url;
7use reqwest::header::HeaderValue;
8use reqwest::Proxy;
9
10use crate::glue::*;
11use crate::util::*;
12
13#[expect(unused_imports, reason = "Used in a doc comment.")]
14use crate::glue::HttpClientConfig;
15
16#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Suitability)]
18#[serde(deny_unknown_fields)]
19#[serde(remote = "Self")]
20pub struct ProxyConfig {
21 pub url: Url,
23 #[serde(default, skip_serializing_if = "is_default")]
27 pub mode: ProxyMode,
28 #[serde(default, skip_serializing_if = "is_default")]
32 pub auth: Option<ProxyAuth>
33}
34
35crate::util::string_or_struct_magic!(ProxyConfig);
36
37impl FromStr for ProxyConfig {
38 type Err = <Url as FromStr>::Err;
39 fn from_str(s: &str) -> Result<Self, Self::Err> {
40 Ok(Url::from_str(s)?.into())
41 }
42}
43
44impl TryFrom<&str> for ProxyConfig {
45 type Error = <Self as FromStr>::Err;
46 fn try_from(value: &str) -> Result<Self, Self::Error> {
47 Self::from_str(value)
48 }
49}
50
51impl From<Url> for ProxyConfig {
52 fn from(url: Url) -> Self {
53 Self {
54 url,
55 mode: ProxyMode::default(),
56 auth: None
57 }
58 }
59}
60
61#[derive(Debug, Clone, Copy, PartialEq, Default, Eq, Serialize, Deserialize, Suitability)]
65#[serde(deny_unknown_fields)]
66pub enum ProxyMode {
67 Http,
71 Https,
75 #[default]
79 All
80}
81
82#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Suitability)]
86#[serde(deny_unknown_fields)]
87pub enum ProxyAuth {
88 Basic {
92 username: String,
94 password: String
96 },
97 Custom(#[serde(with = "serde_headervalue")] HeaderValue)
101}
102
103impl TryFrom<ProxyConfig> for reqwest::Proxy {
104 type Error = reqwest::Error;
105
106 fn try_from(value: ProxyConfig) -> reqwest::Result<Self> {
107 let temp = match value.mode {
108 ProxyMode::Http => Proxy::http (value.url),
109 ProxyMode::Https => Proxy::https(value.url),
110 ProxyMode::All => Proxy::all (value.url)
111 }?;
112 Ok(match &value.auth {
113 None => temp,
114 Some(ProxyAuth::Basic {username, password}) => temp.basic_auth(username, password),
115 Some(ProxyAuth::Custom(value)) => temp.custom_http_auth(value.clone())
116 })
117 }
118}
119
120impl ProxyConfig {
121 pub fn make(self) -> reqwest::Result<Proxy> {
125 self.try_into()
126 }
127}