1use async_trait::async_trait;
2use bytes::Bytes;
3use kithara_platform::time::Duration;
4#[cfg(not(target_arch = "wasm32"))]
5use kithara_platform::tokio;
6#[cfg(not(target_arch = "wasm32"))]
7use tokio::time::timeout;
8use url::Url;
9
10use crate::{
11 ByteStream,
12 error::NetError,
13 traits::Net,
14 types::{Headers, RangeSpec},
15};
16
17pub struct TimeoutNet<N> {
19 inner: N,
20 #[cfg(not(target_arch = "wasm32"))]
21 timeout: Duration,
22}
23
24impl<N: Net> TimeoutNet<N> {
25 #[cfg(not(target_arch = "wasm32"))]
26 pub fn new(inner: N, timeout: Duration) -> Self {
27 Self { inner, timeout }
28 }
29
30 #[cfg(target_arch = "wasm32")]
31 pub fn new(inner: N, _timeout: Duration) -> Self {
32 Self { inner }
33 }
34}
35
36#[cfg(not(target_arch = "wasm32"))]
37#[async_trait]
38impl<N: Net> Net for TimeoutNet<N> {
39 async fn get_bytes(&self, url: Url, headers: Option<Headers>) -> Result<Bytes, NetError> {
40 timeout(self.timeout, self.inner.get_bytes(url, headers))
41 .await
42 .map_err(|_| NetError::timeout())?
43 }
44
45 async fn get_range(
46 &self,
47 url: Url,
48 range: RangeSpec,
49 headers: Option<Headers>,
50 ) -> Result<ByteStream, NetError> {
51 timeout(self.timeout, self.inner.get_range(url, range, headers))
52 .await
53 .map_err(|_| NetError::timeout())?
54 }
55
56 async fn head(&self, url: Url, headers: Option<Headers>) -> Result<Headers, NetError> {
57 timeout(self.timeout, self.inner.head(url, headers))
58 .await
59 .map_err(|_| NetError::timeout())?
60 }
61
62 async fn stream(&self, url: Url, headers: Option<Headers>) -> Result<ByteStream, NetError> {
63 timeout(self.timeout, self.inner.stream(url, headers))
64 .await
65 .map_err(|_| NetError::timeout())?
66 }
67}
68
69#[cfg(target_arch = "wasm32")]
72#[async_trait(?Send)]
73impl<N: Net> Net for TimeoutNet<N> {
74 async fn get_bytes(&self, url: Url, headers: Option<Headers>) -> Result<Bytes, NetError> {
75 self.inner.get_bytes(url, headers).await
76 }
77
78 async fn get_range(
79 &self,
80 url: Url,
81 range: RangeSpec,
82 headers: Option<Headers>,
83 ) -> Result<ByteStream, NetError> {
84 self.inner.get_range(url, range, headers).await
85 }
86
87 async fn head(&self, url: Url, headers: Option<Headers>) -> Result<Headers, NetError> {
88 self.inner.head(url, headers).await
89 }
90
91 async fn stream(&self, url: Url, headers: Option<Headers>) -> Result<ByteStream, NetError> {
92 self.inner.stream(url, headers).await
93 }
94}