cow_sdk_core/config/
http.rs1use std::time::Duration;
2
3use http::HeaderValue;
4
5use crate::errors::ValidationError;
6
7use super::{DEFAULT_HTTP_TIMEOUT, DEFAULT_MAX_RESPONSE_BYTES};
8
9#[non_exhaustive]
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct HttpClientPolicy {
13 timeout: Option<Duration>,
14 user_agent: String,
15 max_response_bytes: usize,
16}
17
18impl HttpClientPolicy {
19 pub fn new(user_agent: impl Into<String>) -> Result<Self, ValidationError> {
26 Self::with_timeout_and_user_agent(DEFAULT_HTTP_TIMEOUT, user_agent)
27 }
28
29 pub fn with_timeout_and_user_agent(
36 timeout: Duration,
37 user_agent: impl Into<String>,
38 ) -> Result<Self, ValidationError> {
39 let user_agent = validate_user_agent(user_agent.into())?;
40
41 Ok(Self {
42 timeout: Some(timeout),
43 user_agent,
44 max_response_bytes: DEFAULT_MAX_RESPONSE_BYTES,
45 })
46 }
47
48 #[must_use]
50 pub const fn without_timeout(mut self) -> Self {
51 self.timeout = None;
52 self
53 }
54
55 #[must_use]
57 pub const fn with_timeout(mut self, timeout: Duration) -> Self {
58 self.timeout = Some(timeout);
59 self
60 }
61
62 #[must_use]
66 pub const fn with_max_response_bytes(mut self, max_response_bytes: usize) -> Self {
67 self.max_response_bytes = max_response_bytes;
68 self
69 }
70
71 pub fn try_with_user_agent(
78 mut self,
79 user_agent: impl Into<String>,
80 ) -> Result<Self, ValidationError> {
81 self.user_agent = validate_user_agent(user_agent.into())?;
82 Ok(self)
83 }
84
85 #[must_use]
87 pub const fn timeout(&self) -> Option<Duration> {
88 self.timeout
89 }
90
91 #[must_use]
93 pub const fn max_response_bytes(&self) -> usize {
94 self.max_response_bytes
95 }
96
97 #[must_use]
99 pub fn user_agent(&self) -> &str {
100 &self.user_agent
101 }
102}
103
104pub(super) fn validate_user_agent(user_agent: String) -> Result<String, ValidationError> {
105 if user_agent.trim().is_empty() {
106 return Err(ValidationError::EmptyField {
107 field: "user_agent",
108 });
109 }
110
111 validate_header_value(&user_agent, "user_agent")?;
112
113 Ok(user_agent)
114}
115
116pub(super) fn validate_header_value(
117 value: &str,
118 field: &'static str,
119) -> Result<(), ValidationError> {
120 HeaderValue::from_str(value).map_err(|_| ValidationError::InvalidHttpHeaderValue { field })?;
121 Ok(())
122}