maplibre/io/
source_client.rs1use async_trait::async_trait;
4use thiserror::Error;
5
6use crate::{coords::WorldTileCoords, io::source_type::SourceType};
7
8pub type HTTPClientFactory<HC> = dyn Fn() -> HC;
10
11#[cfg_attr(not(feature = "thread-safe-futures"), async_trait(?Send))]
18#[cfg_attr(feature = "thread-safe-futures", async_trait)]
19pub trait HttpClient: Clone + Sync + Send + 'static {
20 async fn fetch(&self, url: &str) -> Result<Vec<u8>, SourceFetchError>;
21}
22
23#[derive(Clone)]
26pub struct HttpSourceClient<HC>
27where
28 HC: HttpClient,
29{
30 inner_client: HC,
31}
32
33#[derive(Error, Debug)]
34#[error("failed to fetch from source")]
35pub struct SourceFetchError(#[source] pub Box<dyn std::error::Error>);
36
37#[derive(Clone)]
40pub struct SourceClient<HC>
41where
42 HC: HttpClient,
43{
44 http: HttpSourceClient<HC>,
45}
46
47impl<HC> SourceClient<HC>
48where
49 HC: HttpClient,
50{
51 pub fn new(http: HttpSourceClient<HC>) -> Self {
52 Self { http }
53 }
54
55 pub async fn fetch(
56 &self,
57 coords: &WorldTileCoords,
58 source_type: &SourceType,
59 ) -> Result<Vec<u8>, SourceFetchError> {
60 self.http.fetch(coords, source_type).await
61 }
62}
63
64impl<HC> HttpSourceClient<HC>
65where
66 HC: HttpClient,
67{
68 pub fn new(http_client: HC) -> Self {
69 Self {
70 inner_client: http_client,
71 }
72 }
73
74 pub async fn fetch(
75 &self,
76 coords: &WorldTileCoords,
77 source_type: &SourceType,
78 ) -> Result<Vec<u8>, SourceFetchError> {
79 self.inner_client
80 .fetch(source_type.format(coords).as_str())
81 .await
82 }
83}