read_url/context/
context.rs

1use super::super::{cache::*, internal::*, url::*};
2
3use std::{collections::*, path::*, sync::*};
4
5//
6// UrlContext
7//
8
9/// Common reference type for [UrlContext].
10pub type UrlContextRef = Arc<UrlContext>;
11
12/// Context for [URL](super::super::URL).
13#[derive(Clone, Debug)]
14pub struct UrlContext {
15    /// Base URLs.
16    pub base_urls: Arc<[Arc<UrlRef>]>,
17
18    /// URL overrides.
19    pub url_overrides: Arc<Mutex<HashMap<String, String>>>,
20
21    /// Cache.
22    pub cache: Arc<UrlCache>,
23
24    /// Internal URL registry.
25    pub internal_url_registry: Arc<InternalUrlRegistry>,
26
27    /// Common HTTP client.
28    ///
29    /// Note that we are using the async version of [reqwest::Client] rather than
30    /// the blocking version because 1) the blocking version is not supported in WASM, and
31    /// 2) we can just use a straightforward blocking wrapper on top of the async client.
32    #[cfg(feature = "http")]
33    pub http_client: Arc<LazyLock<reqwest::Client>>,
34}
35
36impl UrlContext {
37    /// Constructor.
38    pub fn new() -> UrlContextRef {
39        UrlContext::new_for(None)
40    }
41
42    /// Constructor.
43    pub fn new_for(cache_base_directory: Option<PathBuf>) -> UrlContextRef {
44        UrlContext {
45            base_urls: [].into(),
46            url_overrides: Arc::new(HashMap::default().into()),
47            cache: UrlCache::new(cache_base_directory).into(),
48            internal_url_registry: Arc::new(HashMap::default().into()),
49
50            #[cfg(feature = "http")]
51            http_client: Arc::new(LazyLock::new(|| Default::default())),
52        }
53        .into()
54    }
55
56    /// Return a child context with different base URLs.
57    ///
58    /// The child context shares everything else with the parent.
59    pub fn with_base_urls<UrlRefT>(self: &UrlContextRef, base_urls: Vec<UrlRefT>) -> UrlContextRef
60    where
61        UrlRefT: Into<Arc<UrlRef>>,
62    {
63        let base_urls: Vec<_> = base_urls.into_iter().map(|url| url.into()).collect();
64
65        UrlContext {
66            base_urls: Arc::from(base_urls),
67            url_overrides: self.url_overrides.clone(),
68            cache: self.cache.clone(),
69            internal_url_registry: self.internal_url_registry.clone(),
70
71            #[cfg(feature = "http")]
72            http_client: self.http_client.clone(),
73        }
74        .into()
75    }
76
77    /// Return a child context with a different cache.
78    ///
79    /// The child context shares everything else with the parent.
80    pub fn with_cache(self: &UrlContextRef, cache_base_directory: Option<PathBuf>) -> UrlContextRef {
81        UrlContext {
82            base_urls: self.base_urls.clone(),
83            url_overrides: self.url_overrides.clone(),
84            cache: UrlCache::new(cache_base_directory).into(),
85            internal_url_registry: self.internal_url_registry.clone(),
86
87            #[cfg(feature = "http")]
88            http_client: self.http_client.clone(),
89        }
90        .into()
91    }
92
93    /// Clone base URLs.
94    pub fn clone_base_urls(&self) -> Vec<Arc<UrlRef>> {
95        self.base_urls.iter().cloned().collect()
96    }
97}