1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use crate::{
    loader::{
        error::LoaderError,
        trait_::{GetCache, GetClient, LoaderTrait},
        Loader,
    },
    thread_safe_cache::ThreadSafeCacheTrait,
    url_helpers::UrlError,
};
use json_trait_rs::{get_fragment, JsonType};
use reqwest::blocking::Client;
use std::sync::Arc;
use url::Url;

#[derive(Debug)]
pub struct ConcreteJsonLoader<T: JsonType>(Loader<T>);

impl<T: JsonType> Default for ConcreteJsonLoader<T> {
    fn default() -> Self {
        Self(Loader::default())
    }
}

impl<T: JsonType> GetCache<T> for ConcreteJsonLoader<T> {
    fn get_cache(&self) -> &dyn ThreadSafeCacheTrait<Url, T> {
        self.0.get_cache()
    }
}

impl<T: JsonType> GetClient<T> for ConcreteJsonLoader<T> {
    fn get_client(&self) -> &Client {
        self.0.get_client()
    }
}

pub trait ToOwnedJsonType: JsonType {
    fn to_owned_json_type(&self) -> Self;
}

impl<T: JsonType + Clone> ToOwnedJsonType for T {
    fn to_owned_json_type(&self) -> Self {
        self.clone()
    }
}

default impl<T: JsonType + ToOwnedJsonType> LoaderTrait<T> for ConcreteJsonLoader<T> {
    default fn extract_fragment(&self, fragment: &str, value: Arc<T>) -> Result<Arc<T>, LoaderError> {
        if let Some(fragment) = get_fragment(&*value, fragment) {
            Ok(Arc::new(fragment.to_owned_json_type()))
        } else {
            Err(LoaderError::InvalidURL(UrlError::JsonFragmentError(format!(
                "Fragment '{}' not found in {}",
                fragment,
                value.to_json_string()
            ))))
        }
    }
}