use std::ffi::OsString;
use std::marker::PhantomData;
use std::num::NonZeroU32;
use std::path::PathBuf;
use crate::renderer::bridge::ffi;
use crate::renderer::{ImageRenderer, MapMode, Static, Tile};
#[derive(Debug, Clone, PartialEq)]
pub struct ImageRendererBuilder {
width: u32,
height: u32,
pixel_ratio: f32,
cache_path: Option<PathBuf>,
asset_root: Option<PathBuf>,
base_url: url::Url,
uri_scheme_alias: String,
source_template: String,
style_template: String,
sprites_template: String,
glyphs_template: String,
tile_template: String,
api_key: String,
api_key_parameter_name: String,
requires_api_key: bool,
}
impl Default for ImageRendererBuilder {
#[allow(clippy::missing_panics_doc, reason = "infallible")]
fn default() -> Self {
Self {
width: 512,
height: 512,
pixel_ratio: 1.0,
cache_path: None,
asset_root: std::env::current_dir().ok(),
base_url: "https://demotiles.maplibre.org"
.parse()
.expect("is a valid url"),
uri_scheme_alias: "maplibre".to_string(),
source_template: "/tiles/{domain}.json".to_string(),
style_template: "{path}.json".to_string(),
sprites_template: "/{path}/sprite{scale}.{format}".to_string(),
glyphs_template: "/font/{fontstack}/{start}-{end}.pbf".to_string(),
tile_template: "/{path}".to_string(),
api_key_parameter_name: String::new(),
api_key: String::new(),
requires_api_key: false,
}
}
}
impl ImageRendererBuilder {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
#[allow(clippy::needless_pass_by_value, reason = "false positive")]
pub fn with_size(mut self, width: NonZeroU32, height: NonZeroU32) -> Self {
self.width = width.get();
self.height = height.get();
self
}
#[must_use]
#[allow(clippy::needless_pass_by_value, reason = "false positive")]
pub fn with_pixel_ratio(mut self, pixel_ratio: impl Into<f32>) -> Self {
self.pixel_ratio = pixel_ratio.into();
self
}
#[must_use]
#[allow(clippy::needless_pass_by_value, reason = "false positive")]
pub fn with_cache_path(mut self, cache_path: impl Into<PathBuf>) -> Self {
self.cache_path = Some(cache_path.into());
self
}
#[must_use]
#[allow(clippy::needless_pass_by_value, reason = "false positive")]
pub fn with_asset_root(mut self, asset_root: impl Into<PathBuf>) -> Self {
self.asset_root = Some(asset_root.into());
self
}
#[must_use]
#[allow(clippy::needless_pass_by_value, reason = "false positive")]
pub fn with_base_url(mut self, base_url: url::Url) -> Self {
self.base_url = base_url;
self
}
#[must_use]
#[allow(clippy::needless_pass_by_value, reason = "false positive")]
pub fn with_uri_scheme_alias(mut self, uri_scheme_alias: impl ToString) -> Self {
self.uri_scheme_alias = uri_scheme_alias.to_string();
self
}
#[must_use]
#[allow(clippy::needless_pass_by_value, reason = "false positive")]
pub fn with_source_template(mut self, source_template: impl ToString) -> Self {
self.source_template = source_template.to_string();
self
}
#[must_use]
#[allow(clippy::needless_pass_by_value, reason = "false positive")]
pub fn with_style_template(mut self, style_template: impl ToString) -> Self {
self.style_template = style_template.to_string();
self
}
#[must_use]
#[allow(clippy::needless_pass_by_value, reason = "false positive")]
pub fn with_sprites_template(mut self, sprites_template: impl ToString) -> Self {
self.sprites_template = sprites_template.to_string();
self
}
#[must_use]
#[allow(clippy::needless_pass_by_value, reason = "false positive")]
pub fn with_glyphs_template(mut self, glyphs_template: impl ToString) -> Self {
self.glyphs_template = glyphs_template.to_string();
self
}
#[must_use]
#[allow(clippy::needless_pass_by_value, reason = "false positive")]
pub fn with_tile_template(mut self, tile_template: impl ToString) -> Self {
self.tile_template = tile_template.to_string();
self
}
#[must_use]
#[allow(clippy::needless_pass_by_value, reason = "false positive")]
pub fn with_api_key_parameter_name(mut self, api_key_parameter_name: impl ToString) -> Self {
self.api_key_parameter_name = api_key_parameter_name.to_string();
self
}
#[must_use]
#[allow(clippy::needless_pass_by_value, reason = "false positive")]
pub fn with_api_key(mut self, api_key: impl ToString) -> Self {
self.api_key = api_key.to_string();
self
}
#[must_use]
pub fn set_requires_api_key(mut self, requires_api_key: impl Into<bool>) -> Self {
self.requires_api_key = requires_api_key.into();
self
}
#[must_use]
pub fn build_static_renderer(self) -> ImageRenderer<Static> {
ImageRenderer::new(MapMode::Static, self)
}
#[must_use]
pub fn build_tile_renderer(self) -> ImageRenderer<Tile> {
ImageRenderer::new(MapMode::Tile, self)
}
}
impl<S> ImageRenderer<S> {
fn new(map_mode: MapMode, opts: ImageRendererBuilder) -> Self {
let map = ffi::MapRenderer_new(
map_mode,
opts.width,
opts.height,
opts.pixel_ratio,
opts.cache_path
.map_or(OsString::new(), PathBuf::into_os_string)
.as_encoded_bytes(),
opts.asset_root
.map_or(OsString::new(), PathBuf::into_os_string)
.as_encoded_bytes(),
&opts.api_key,
opts.base_url.as_ref(),
&opts.uri_scheme_alias,
&opts.api_key_parameter_name,
&opts.source_template,
&opts.style_template,
&opts.sprites_template,
&opts.glyphs_template,
&opts.tile_template,
opts.requires_api_key,
);
Self {
instance: map,
style_specified: false,
_marker: PhantomData,
}
}
}