Skip to main content

referencing/
retriever.rs

1use core::fmt;
2
3use fluent_uri::Uri;
4use serde_json::Value;
5
6#[cfg(target_family = "wasm")]
7pub trait RetrieverBounds {}
8
9#[cfg(target_family = "wasm")]
10impl<T: ?Sized> RetrieverBounds for T {}
11
12#[cfg(not(target_family = "wasm"))]
13pub trait RetrieverBounds: Send + Sync {}
14
15#[cfg(not(target_family = "wasm"))]
16impl<T: ?Sized + Send + Sync> RetrieverBounds for T {}
17
18/// Trait for retrieving resources from external sources.
19///
20/// Implementors of this trait can be used to fetch resources that are not
21/// initially present in a [`crate::Registry`].
22pub trait Retrieve: RetrieverBounds {
23    /// Attempt to retrieve a resource from the given URI.
24    ///
25    /// # Arguments
26    ///
27    /// * `uri` - The URI of the resource to retrieve.
28    ///
29    /// # Errors
30    ///
31    /// This method can fail for various reasons:
32    /// - Resource not found
33    /// - Network errors (for remote resources)
34    /// - Permission errors
35    fn retrieve(
36        &self,
37        uri: &Uri<String>,
38    ) -> Result<Value, Box<dyn std::error::Error + Send + Sync>>;
39}
40
41#[derive(Debug, Clone)]
42struct DefaultRetrieverError;
43
44impl fmt::Display for DefaultRetrieverError {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        f.write_str("Default retriever does not fetch resources")
47    }
48}
49
50impl std::error::Error for DefaultRetrieverError {}
51
52/// A retriever that always fails, used as a default when external resource fetching is not needed.
53#[derive(Debug, PartialEq, Eq)]
54pub struct DefaultRetriever;
55
56impl Retrieve for DefaultRetriever {
57    fn retrieve(&self, _: &Uri<String>) -> Result<Value, Box<dyn std::error::Error + Send + Sync>> {
58        Err(Box::new(DefaultRetrieverError))
59    }
60}
61
62#[cfg(feature = "retrieve-async")]
63#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
64#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
65pub trait AsyncRetrieve: RetrieverBounds {
66    /// Asynchronously retrieve a resource from the given URI.
67    ///
68    /// This is the non-blocking equivalent of [`Retrieve::retrieve`].
69    ///
70    /// # Arguments
71    ///
72    /// * `uri` - The URI of the resource to retrieve.
73    ///
74    /// # Errors
75    ///
76    /// This method can fail for various reasons:
77    /// - Resource not found
78    /// - Network errors (for remote resources)
79    /// - Permission errors
80    async fn retrieve(
81        &self,
82        uri: &Uri<String>,
83    ) -> Result<Value, Box<dyn std::error::Error + Send + Sync>>;
84}
85
86#[cfg(feature = "retrieve-async")]
87#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
88#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
89impl AsyncRetrieve for DefaultRetriever {
90    async fn retrieve(
91        &self,
92        _: &Uri<String>,
93    ) -> Result<Value, Box<dyn std::error::Error + Send + Sync>> {
94        Err(Box::new(DefaultRetrieverError))
95    }
96}