#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(dead_code)]
use libc::{c_char, c_double, c_float, c_uchar, c_uint, c_void, size_t};
#[repr(C)]
pub struct MLNMap {
_private: [u8; 0],
}
#[repr(C)]
pub struct MLNHeadlessFrontend {
_private: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MLNErrorCode {
MLN_OK = 0,
MLN_ERROR_INVALID_ARGUMENT = 1,
MLN_ERROR_STYLE_PARSE = 2,
MLN_ERROR_RENDER_FAILED = 3,
MLN_ERROR_NOT_LOADED = 4,
MLN_ERROR_TIMEOUT = 5,
MLN_ERROR_UNKNOWN = 99,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MLNMapMode {
MLN_MAP_MODE_STATIC = 0,
MLN_MAP_MODE_TILE = 1,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MLNDebugOptions {
MLN_DEBUG_NONE = 0,
MLN_DEBUG_TILE_BORDERS = 1,
MLN_DEBUG_PARSE_STATUS = 2,
MLN_DEBUG_TIMESTAMPS = 4,
MLN_DEBUG_COLLISION = 8,
MLN_DEBUG_OVERDRAW = 16,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, Default)]
pub struct MLNSize {
pub width: c_uint,
pub height: c_uint,
}
impl MLNSize {
pub fn new(width: u32, height: u32) -> Self {
Self { width, height }
}
}
#[repr(C)]
#[derive(Debug, Clone, Copy, Default)]
pub struct MLNCameraOptions {
pub latitude: c_double,
pub longitude: c_double,
pub zoom: c_double,
pub bearing: c_double,
pub pitch: c_double,
}
impl MLNCameraOptions {
pub fn new(latitude: f64, longitude: f64, zoom: f64) -> Self {
Self {
latitude,
longitude,
zoom,
bearing: 0.0,
pitch: 0.0,
}
}
pub fn with_bearing(mut self, bearing: f64) -> Self {
self.bearing = bearing;
self
}
pub fn with_pitch(mut self, pitch: f64) -> Self {
self.pitch = pitch;
self
}
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct MLNRenderOptions {
pub size: MLNSize,
pub pixel_ratio: c_float,
pub camera: MLNCameraOptions,
pub mode: MLNMapMode,
pub debug: MLNDebugOptions,
}
impl Default for MLNRenderOptions {
fn default() -> Self {
Self {
size: MLNSize::new(512, 512),
pixel_ratio: 1.0,
camera: MLNCameraOptions::default(),
mode: MLNMapMode::MLN_MAP_MODE_TILE,
debug: MLNDebugOptions::MLN_DEBUG_NONE,
}
}
}
#[repr(C)]
#[derive(Debug)]
pub struct MLNImageData {
pub data: *mut c_uchar,
pub data_len: size_t,
pub width: c_uint,
pub height: c_uint,
}
impl Default for MLNImageData {
fn default() -> Self {
Self {
data: std::ptr::null_mut(),
data_len: 0,
width: 0,
height: 0,
}
}
}
#[repr(C)]
#[derive(Debug)]
pub struct MLNResourceRequest {
pub url: *const c_char,
pub kind: c_uchar,
}
#[repr(C)]
#[derive(Debug)]
pub struct MLNResourceResponse {
pub data: *const c_uchar,
pub data_len: size_t,
pub error: *const c_char,
pub not_found: bool,
}
impl Default for MLNResourceResponse {
fn default() -> Self {
Self {
data: std::ptr::null(),
data_len: 0,
error: std::ptr::null(),
not_found: false,
}
}
}
pub type MLNRenderCallback = Option<
unsafe extern "C" fn(error: MLNErrorCode, image: *mut MLNImageData, user_data: *mut c_void),
>;
pub type MLNResourceCallback = Option<
unsafe extern "C" fn(
request: *const MLNResourceRequest,
response: *mut MLNResourceResponse,
user_data: *mut c_void,
),
>;
unsafe extern "C" {
pub fn mln_init() -> MLNErrorCode;
pub fn mln_cleanup();
pub fn mln_headless_frontend_create(
size: MLNSize,
pixel_ratio: c_float,
) -> *mut MLNHeadlessFrontend;
pub fn mln_headless_frontend_destroy(frontend: *mut MLNHeadlessFrontend);
pub fn mln_headless_frontend_set_size(frontend: *mut MLNHeadlessFrontend, size: MLNSize);
pub fn mln_headless_frontend_get_size(frontend: *mut MLNHeadlessFrontend) -> MLNSize;
pub fn mln_map_create(
frontend: *mut MLNHeadlessFrontend,
pixel_ratio: c_float,
mode: MLNMapMode,
) -> *mut MLNMap;
pub fn mln_map_create_with_loader(
frontend: *mut MLNHeadlessFrontend,
pixel_ratio: c_float,
mode: MLNMapMode,
request_callback: MLNResourceCallback,
user_data: *mut c_void,
) -> *mut MLNMap;
pub fn mln_map_destroy(map: *mut MLNMap);
pub fn mln_map_load_style(map: *mut MLNMap, style_json: *const c_char) -> MLNErrorCode;
pub fn mln_map_load_style_url(map: *mut MLNMap, url: *const c_char) -> MLNErrorCode;
pub fn mln_map_is_fully_loaded(map: *mut MLNMap) -> bool;
pub fn mln_map_set_camera(map: *mut MLNMap, camera: *const MLNCameraOptions);
pub fn mln_map_get_camera(map: *mut MLNMap) -> MLNCameraOptions;
pub fn mln_map_set_size(map: *mut MLNMap, size: MLNSize);
pub fn mln_map_set_debug(map: *mut MLNMap, options: MLNDebugOptions);
pub fn mln_map_render_still(
map: *mut MLNMap,
options: *const MLNRenderOptions,
image: *mut MLNImageData,
) -> MLNErrorCode;
pub fn mln_map_render_still_async(
map: *mut MLNMap,
options: *const MLNRenderOptions,
callback: MLNRenderCallback,
user_data: *mut c_void,
);
pub fn mln_image_free(image: *mut MLNImageData);
pub fn mln_get_last_error() -> *const c_char;
pub fn mln_map_add_image(
map: *mut MLNMap,
id: *const c_char,
data: *const c_uchar,
width: c_uint,
height: c_uint,
pixel_ratio: c_float,
sdf: bool,
) -> MLNErrorCode;
pub fn mln_map_remove_image(map: *mut MLNMap, id: *const c_char) -> MLNErrorCode;
pub fn mln_set_base_path(path: *const c_char);
pub fn mln_set_api_key(key: *const c_char);
}
pub mod resource_kind {
pub const UNKNOWN: u8 = 0;
pub const STYLE: u8 = 1;
pub const SOURCE: u8 = 2;
pub const TILE: u8 = 3;
pub const GLYPHS: u8 = 4;
pub const SPRITE_IMAGE: u8 = 5;
pub const SPRITE_JSON: u8 = 6;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_size_layout() {
assert_eq!(std::mem::size_of::<MLNSize>(), 8);
}
#[test]
fn test_camera_options() {
let camera = MLNCameraOptions::new(37.8, -122.4, 12.0)
.with_bearing(45.0)
.with_pitch(30.0);
assert_eq!(camera.latitude, 37.8);
assert_eq!(camera.longitude, -122.4);
assert_eq!(camera.zoom, 12.0);
assert_eq!(camera.bearing, 45.0);
assert_eq!(camera.pitch, 30.0);
}
}