use std::{
concat, env,
fmt::{Display, Formatter},
};
#[cfg(static_tiles_found)]
use include_dir::include_dir;
use include_dir::Dir;
use crate::coords::TileCoords;
#[cfg(static_tiles_found)]
static TILES: Dir = include_dir!("$OUT_DIR/extracted-tiles");
#[cfg(not(static_tiles_found))]
static TILES: Dir = Dir::new("/path", &[]);
#[derive(Debug)]
pub enum StaticFetchError {
NotFound,
}
impl Display for StaticFetchError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
#[derive(Default)]
pub struct StaticTileFetcher;
impl StaticTileFetcher {
pub fn get_source_path() -> &'static str {
concat!(env!("OUT_DIR"), "/extracted-tiles")
}
pub fn new() -> Self {
Self {}
}
pub async fn fetch_tile(&self, coords: &TileCoords) -> Result<Vec<u8>, StaticFetchError> {
self.sync_fetch_tile(coords)
}
pub fn sync_fetch_tile(&self, coords: &TileCoords) -> Result<Vec<u8>, StaticFetchError> {
if TILES.entries().is_empty() {
panic!(
"There are not tiles statically embedded in this binary! StaticTileFetcher will \
not return any tiles!"
)
}
let tile = TILES
.get_file(format!("{}/{}/{}.{}", coords.z, coords.x, coords.y, "pbf"))
.ok_or_else(|| StaticFetchError::NotFound)?;
Ok(Vec::from(tile.contents()))
}
}
#[cfg(test)]
mod tests {
use super::StaticTileFetcher;
use crate::{coords::WorldTileCoords, style::source::TileAddressingScheme};
#[cfg(static_tiles_found)]
#[tokio::test]
async fn test_tiles_available() {
const MUNICH_X: i32 = 17425;
const MUNICH_Y: i32 = 11365;
const MUNICH_Z: u8 = 15;
let fetcher = StaticTileFetcher::new();
assert!(fetcher.fetch_tile(&(0, 0, 0).into()).await.is_err()); let world_tile: WorldTileCoords = (MUNICH_X, MUNICH_Y, MUNICH_Z).into();
assert!(fetcher
.fetch_tile(&world_tile.into_tile(TileAddressingScheme::XYZ).unwrap())
.await
.is_ok()); }
}