Skip to content

Commit

Permalink
Make fonts and sprites optional compilable features (#1097)
Browse files Browse the repository at this point in the history
  • Loading branch information
nyurik authored Dec 24, 2023
1 parent f13c3f7 commit 60f3ff9
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 22 deletions.
11 changes: 7 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,13 @@ jobs:
- uses: Swatinem/rust-cache@v2
if: github.event_name != 'release' && github.event_name != 'workflow_dispatch'
- run: cargo fmt --all -- --check
- run: cargo clippy --package martin-tile-utils -- -D warnings
- run: cargo clippy --package mbtiles --no-default-features -- -D warnings
- run: cargo clippy --package mbtiles -- -D warnings
- run: cargo clippy --package martin -- -D warnings
- run: cargo clippy --package martin-tile-utils --tests --lib --bins --benches -- -D warnings
- run: cargo clippy --package mbtiles --tests --lib --bins --benches --no-default-features -- -D warnings
- run: cargo clippy --package mbtiles --tests --lib --bins --benches -- -D warnings
- run: cargo clippy --package martin --tests --lib --bins --benches -- -D warnings
- run: RUSTFLAGS='-D warnings' cargo check --package martin --tests --lib --bins --benches --no-default-features
- run: RUSTFLAGS='-D warnings' cargo check --package martin --tests --lib --bins --benches --no-default-features --features fonts
- run: RUSTFLAGS='-D warnings' cargo check --package martin --tests --lib --bins --benches --no-default-features --features sprites
- run: cargo clippy --package martin --features bless-tests -- -D warnings
- run: cargo doc --no-deps --workspace
env:
Expand Down
4 changes: 3 additions & 1 deletion martin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ name = "bench"
harness = false

[features]
default = []
default = ["sprites", "fonts"]
sprites = []
fonts = []
bless-tests = []

[dependencies]
Expand Down
1 change: 1 addition & 0 deletions martin/src/args/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ impl Args {
config.mbtiles = parse_file_args(&mut cli_strings, "mbtiles", false);
}

#[cfg(feature = "sprites")]
if !self.extras.sprite.is_empty() {
config.sprites = FileConfigEnum::new(self.extras.sprite);
}
Expand Down
24 changes: 18 additions & 6 deletions martin/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ use serde::{Deserialize, Serialize};
use subst::VariableMap;

use crate::file_config::{resolve_files, resolve_files_urls, FileConfigEnum};
#[cfg(feature = "fonts")]
use crate::fonts::FontSources;
use crate::mbtiles::MbtSource;
use crate::pg::PgConfig;
use crate::pmtiles::{PmtFileSource, PmtHttpSource};
use crate::source::{TileInfoSources, TileSources};
#[cfg(feature = "sprites")]
use crate::sprites::SpriteSources;
use crate::srv::SrvConfig;
use crate::MartinError::{ConfigLoadError, ConfigParseError, ConfigWriteError, NoSources};
Expand All @@ -26,7 +28,9 @@ pub type UnrecognizedValues = HashMap<String, serde_yaml::Value>;

pub struct ServerState {
pub tiles: TileSources,
#[cfg(feature = "sprites")]
pub sprites: SpriteSources,
#[cfg(feature = "fonts")]
pub fonts: FontSources,
}

Expand All @@ -44,6 +48,7 @@ pub struct Config {
#[serde(default, skip_serializing_if = "FileConfigEnum::is_none")]
pub mbtiles: FileConfigEnum,

#[cfg(feature = "sprites")]
#[serde(default, skip_serializing_if = "FileConfigEnum::is_none")]
pub sprites: FileConfigEnum,

Expand All @@ -66,17 +71,22 @@ impl Config {

res.extend(self.pmtiles.finalize("pmtiles.")?);
res.extend(self.mbtiles.finalize("mbtiles.")?);
#[cfg(feature = "sprites")]
res.extend(self.sprites.finalize("sprites.")?);

// TODO: support for unrecognized fonts?
// res.extend(self.fonts.finalize("fonts.")?);

if self.postgres.is_empty()
&& self.pmtiles.is_empty()
&& self.mbtiles.is_empty()
&& self.sprites.is_empty()
&& self.fonts.is_empty()
{
let is_empty =
self.postgres.is_empty() && self.pmtiles.is_empty() && self.mbtiles.is_empty();

#[cfg(feature = "sprites")]
let is_empty = is_empty && self.sprites.is_empty();

#[cfg(feature = "fonts")]
let is_empty = is_empty && self.fonts.is_empty();

if is_empty {
Err(NoSources)
} else {
Ok(res)
Expand All @@ -86,7 +96,9 @@ impl Config {
pub async fn resolve(&mut self, idr: IdResolver) -> MartinResult<ServerState> {
Ok(ServerState {
tiles: self.resolve_tile_sources(idr).await?,
#[cfg(feature = "sprites")]
sprites: SpriteSources::resolve(&mut self.sprites)?,
#[cfg(feature = "fonts")]
fonts: FontSources::resolve(&mut self.fonts)?,
})
}
Expand Down
2 changes: 2 additions & 0 deletions martin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ pub use utils::{

pub mod args;
pub mod file_config;
#[cfg(feature = "fonts")]
pub mod fonts;
pub mod mbtiles;
pub mod pg;
pub mod pmtiles;
#[cfg(feature = "sprites")]
pub mod sprites;
pub mod srv;

Expand Down
41 changes: 30 additions & 11 deletions martin/src/srv/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use actix_http::ContentEncoding;
use actix_web::dev::Server;
use actix_web::error::{ErrorBadRequest, ErrorInternalServerError, ErrorNotFound};
use actix_web::http::header::{
AcceptEncoding, ContentType, Encoding as HeaderEnc, Preference, CACHE_CONTROL, CONTENT_ENCODING,
AcceptEncoding, Encoding as HeaderEnc, Preference, CACHE_CONTROL, CONTENT_ENCODING,
};
use actix_web::http::Uri;
use actix_web::middleware::TrailingSlash;
Expand All @@ -23,8 +23,10 @@ use serde::{Deserialize, Serialize};
use tilejson::{tilejson, TileJSON};

use crate::config::ServerState;
#[cfg(feature = "fonts")]
use crate::fonts::{FontCatalog, FontError, FontSources};
use crate::source::{Source, TileCatalog, TileSources, UrlQuery};
#[cfg(feature = "sprites")]
use crate::sprites::{SpriteCatalog, SpriteError, SpriteSources};
use crate::srv::config::{SrvConfig, KEEP_ALIVE_DEFAULT, LISTEN_ADDRESSES_DEFAULT};
use crate::utils::{decode_brotli, decode_gzip, encode_brotli, encode_gzip};
Expand All @@ -48,15 +50,19 @@ static SUPPORTED_ENCODINGS: &[HeaderEnc] = &[
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
pub struct Catalog {
pub tiles: TileCatalog,
#[cfg(feature = "sprites")]
pub sprites: SpriteCatalog,
#[cfg(feature = "fonts")]
pub fonts: FontCatalog,
}

impl Catalog {
pub fn new(state: &ServerState) -> MartinResult<Self> {
Ok(Self {
tiles: state.tiles.get_catalog(),
#[cfg(feature = "sprites")]
sprites: state.sprites.get_catalog()?,
#[cfg(feature = "fonts")]
fonts: state.fonts.get_catalog(),
})
}
Expand All @@ -80,6 +86,7 @@ pub fn map_internal_error<T: std::fmt::Display>(e: T) -> actix_web::Error {
ErrorInternalServerError(e.to_string())
}

#[cfg(feature = "sprites")]
pub fn map_sprite_error(e: SpriteError) -> actix_web::Error {
use SpriteError::SpriteNotFound;
match e {
Expand All @@ -88,6 +95,7 @@ pub fn map_sprite_error(e: SpriteError) -> actix_web::Error {
}
}

#[cfg(feature = "fonts")]
pub fn map_font_error(e: FontError) -> actix_web::Error {
#[allow(clippy::enum_glob_use)]
use FontError::*;
Expand Down Expand Up @@ -131,6 +139,7 @@ async fn get_catalog(catalog: Data<Catalog>) -> impl Responder {
HttpResponse::Ok().json(catalog)
}

#[cfg(feature = "sprites")]
#[route("/sprite/{source_ids}.png", method = "GET", method = "HEAD")]
async fn get_sprite_png(
path: Path<TileJsonRequest>,
Expand All @@ -141,10 +150,11 @@ async fn get_sprite_png(
.await
.map_err(map_sprite_error)?;
Ok(HttpResponse::Ok()
.content_type(ContentType::png())
.content_type(actix_web::http::header::ContentType::png())
.body(sheet.encode_png().map_err(map_internal_error)?))
}

#[cfg(feature = "sprites")]
#[route(
"/sprite/{source_ids}.json",
method = "GET",
Expand All @@ -162,13 +172,15 @@ async fn get_sprite_json(
Ok(HttpResponse::Ok().json(sheet.get_index()))
}

#[cfg(feature = "fonts")]
#[derive(Deserialize, Debug)]
struct FontRequest {
fontstack: String,
start: u32,
end: u32,
}

#[cfg(feature = "fonts")]
#[route(
"/font/{fontstack}/{start}-{end}",
method = "GET",
Expand Down Expand Up @@ -495,10 +507,13 @@ pub fn router(cfg: &mut web::ServiceConfig) {
.service(get_index)
.service(get_catalog)
.service(git_source_info)
.service(get_tile)
.service(get_sprite_json)
.service(get_sprite_png)
.service(get_font);
.service(get_tile);

#[cfg(feature = "sprites")]
cfg.service(get_sprite_json).service(get_sprite_png);

#[cfg(feature = "fonts")]
cfg.service(get_font);
}

/// Create a new initialized Actix `App` instance together with the listening address.
Expand All @@ -515,11 +530,15 @@ pub fn new_server(config: SrvConfig, state: ServerState) -> MartinResult<(Server
.allow_any_origin()
.allowed_methods(vec!["GET"]);

App::new()
.app_data(Data::new(state.tiles.clone()))
.app_data(Data::new(state.sprites.clone()))
.app_data(Data::new(state.fonts.clone()))
.app_data(Data::new(catalog.clone()))
let app = App::new().app_data(Data::new(state.tiles.clone()));

#[cfg(feature = "sprites")]
let app = app.app_data(Data::new(state.sprites.clone()));

#[cfg(feature = "fonts")]
let app = app.app_data(Data::new(state.fonts.clone()));

app.app_data(Data::new(catalog.clone()))
.wrap(cors_middleware)
.wrap(middleware::NormalizePath::new(TrailingSlash::MergeOnly))
.wrap(middleware::Logger::default())
Expand Down
4 changes: 4 additions & 0 deletions martin/src/utils/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ use std::path::PathBuf;
use mbtiles::MbtError;

use crate::file_config::FileError;
#[cfg(feature = "fonts")]
use crate::fonts::FontError;
use crate::pg::PgError;
#[cfg(feature = "sprites")]
use crate::sprites::SpriteError;

/// A convenience [`Result`] for Martin crate.
Expand Down Expand Up @@ -65,9 +67,11 @@ pub enum MartinError {
#[error(transparent)]
FileError(#[from] FileError),

#[cfg(feature = "sprites")]
#[error(transparent)]
SpriteError(#[from] SpriteError),

#[cfg(feature = "fonts")]
#[error(transparent)]
FontError(#[from] FontError),

Expand Down

0 comments on commit 60f3ff9

Please sign in to comment.