1#![deny(unsafe_op_in_unsafe_fn)]
9
10mod camera;
11mod custom_geometry;
12mod events;
13mod geojson;
14mod geometry;
15mod handle;
16mod json;
17mod logging;
18mod map;
19mod options;
20mod projection;
21mod render;
22mod resource;
23mod runtime;
24mod values;
25
26use crate::values::NativeValue;
27use maplibre_native_core as maplibre_core;
28use maplibre_native_sys as sys;
29
30pub use camera::{
31 AnimationOptions, BoundOptions, CameraFitOptions, CameraOptions, FreeCameraOptions,
32 ProjectionMode,
33};
34pub use custom_geometry::{CanonicalTileId, CustomGeometrySourceOptions};
35pub use events::{
36 MapId, OfflineOperationCompletedEvent, OfflineRegionResponseErrorEvent, OfflineRegionStatus,
37 OfflineRegionStatusEvent, OfflineRegionTileCountLimitEvent, RenderFrameEvent, RenderMapEvent,
38 RenderingStats, RuntimeEvent, RuntimeEventPayload, RuntimeEventSource, StyleImageMissingEvent,
39 TileActionEvent, TileId, UnknownRuntimeEventPayload,
40};
41pub use geojson::{Feature, FeatureIdentifier, GeoJson};
42pub use geometry::Geometry;
43pub use json::{JsonMember, JsonValue};
44pub use logging::{LogRecord, clear_log_callback, set_async_log_severity_mask, set_log_callback};
45pub use map::{
46 LocationIndicatorImageKind, MapHandle, RasterDemEncoding, SourceInfo, SourceType, StyleImage,
47 StyleImageInfo, StyleImageOptions, TileScheme, TileSourceOptions, VectorTileEncoding,
48};
49pub use maplibre_core::{
50 AmbientCacheOperation, ConstrainMode, Error, ErrorKind, LogEvent, LogSeverity, LogSeverityMask,
51 MapDebugOptions, MapMode, MapOptions, MapTileOptions, MapViewportOptions, NetworkStatus,
52 NorthOrientation, OfflineOperationKind, OfflineOperationResultKind, OfflineRegionDownloadState,
53 OpenGLContextProviderMask, RenderBackendMask, RenderMode, ResourceErrorReason, ResourceKind,
54 ResourceLoadingMethod, ResourcePriority, ResourceResponseStatus, ResourceStoragePolicy,
55 ResourceUsage, Result, RuntimeEventType, TileLodMode, TileOperation, ViewportMode,
56};
57pub use projection::MapProjectionHandle;
58pub use render::{
59 DetachedRenderSessionHandle, EglContextDescriptor, FeatureExtensionResult,
60 FeatureStateSelector, FrameNativePointer, FrameOpenGLTextureName,
61 MetalBorrowedTextureDescriptor, MetalContextDescriptor, MetalOwnedTextureDescriptor,
62 MetalOwnedTextureFrame, MetalOwnedTextureFrameHandle, MetalSurfaceDescriptor, NativePointer,
63 OpenGLBorrowedTextureDescriptor, OpenGLContextDescriptor, OpenGLOwnedTextureDescriptor,
64 OpenGLOwnedTextureFrame, OpenGLOwnedTextureFrameHandle, OpenGLSurfaceDescriptor,
65 PremultipliedRgba8Image, QueriedFeature, RenderSessionHandle, RenderTargetExtent,
66 RenderedFeatureQueryOptions, RenderedQueryGeometry, SourceFeatureQueryOptions,
67 TextureImageInfo, VulkanBorrowedTextureDescriptor, VulkanContextDescriptor,
68 VulkanOwnedTextureDescriptor, VulkanOwnedTextureFrame, VulkanOwnedTextureFrameHandle,
69 VulkanSurfaceDescriptor, WglContextDescriptor,
70};
71pub use resource::{
72 ByteRange, ResourceProviderDecision, ResourceRequest, ResourceRequestHandle, ResourceResponse,
73 ResourceTransformRequest,
74};
75pub use runtime::{
76 OfflineOperationHandle, OfflineRegionDefinition, OfflineRegionInfo, RuntimeHandle,
77 RuntimeOptions,
78};
79pub use values::{
80 EdgeInsets, LatLng, LatLngBounds, ProjectedMeters, Quaternion, ScreenBox, ScreenPoint,
81 UnitBezier, Vec3,
82};
83
84#[derive(Debug)]
87pub struct HandleOperationError<T> {
88 error: Error,
89 handle: T,
90}
91
92impl<T> HandleOperationError<T> {
93 pub(crate) fn new(error: Error, handle: T) -> Self {
94 Self { error, handle }
95 }
96
97 pub fn error(&self) -> &Error {
99 &self.error
100 }
101
102 pub fn kind(&self) -> ErrorKind {
104 self.error.kind()
105 }
106
107 pub fn raw_status(&self) -> Option<i32> {
109 self.error.raw_status()
110 }
111
112 pub fn diagnostic(&self) -> &str {
114 self.error.diagnostic()
115 }
116
117 pub fn into_error(self) -> Error {
119 self.error
120 }
121
122 pub fn into_handle(self) -> T {
124 self.handle
125 }
126
127 pub fn into_parts(self) -> (Error, T) {
129 (self.error, self.handle)
130 }
131}
132
133impl<T> std::fmt::Display for HandleOperationError<T> {
134 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135 self.error.fmt(f)
136 }
137}
138
139impl<T: std::fmt::Debug> std::error::Error for HandleOperationError<T> {}
140
141#[derive(Debug)]
143pub enum OfflineOperationTakeError<T> {
144 Retryable(HandleOperationError<T>),
146 Consumed(Error),
148}
149
150impl<T> OfflineOperationTakeError<T> {
151 pub(crate) fn retryable(error: Error, handle: T) -> Self {
152 Self::Retryable(HandleOperationError::new(error, handle))
153 }
154
155 pub(crate) fn consumed(error: Error) -> Self {
156 Self::Consumed(error)
157 }
158
159 pub fn error(&self) -> &Error {
161 match self {
162 Self::Retryable(error) => error.error(),
163 Self::Consumed(error) => error,
164 }
165 }
166
167 pub fn kind(&self) -> ErrorKind {
169 self.error().kind()
170 }
171
172 pub fn raw_status(&self) -> Option<i32> {
174 self.error().raw_status()
175 }
176
177 pub fn diagnostic(&self) -> &str {
179 self.error().diagnostic()
180 }
181
182 pub fn into_retryable(self) -> Option<HandleOperationError<T>> {
184 match self {
185 Self::Retryable(error) => Some(error),
186 Self::Consumed(_) => None,
187 }
188 }
189
190 pub fn into_error(self) -> Error {
192 match self {
193 Self::Retryable(error) => error.into_error(),
194 Self::Consumed(error) => error,
195 }
196 }
197}
198
199impl<T> std::fmt::Display for OfflineOperationTakeError<T> {
200 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
201 self.error().fmt(f)
202 }
203}
204
205impl<T: std::fmt::Debug> std::error::Error for OfflineOperationTakeError<T> {}
206
207pub fn c_version() -> u32 {
209 unsafe { sys::mln_c_version() }
212}
213
214pub fn supported_render_backends() -> RenderBackendMask {
216 let mask = unsafe { sys::mln_supported_render_backend_mask() };
219 RenderBackendMask::from_bits_retain(mask)
220}
221
222pub fn supported_opengl_context_providers() -> OpenGLContextProviderMask {
224 let mask = unsafe { sys::mln_opengl_supported_context_provider_mask() };
227 OpenGLContextProviderMask::from_bits_retain(mask)
228}
229
230pub fn projected_meters_for_lat_lng(coordinate: LatLng) -> Result<ProjectedMeters> {
232 let mut raw_meters = sys::mln_projected_meters {
233 northing: 0.0,
234 easting: 0.0,
235 };
236 maplibre_core::check(unsafe {
239 sys::mln_projected_meters_for_lat_lng(coordinate.to_native(), &mut raw_meters)
240 })?;
241 Ok(ProjectedMeters::from_native(raw_meters))
242}
243
244pub fn lat_lng_for_projected_meters(meters: ProjectedMeters) -> Result<LatLng> {
246 let mut raw_coordinate = sys::mln_lat_lng {
247 latitude: 0.0,
248 longitude: 0.0,
249 };
250 maplibre_core::check(unsafe {
253 sys::mln_lat_lng_for_projected_meters(meters.to_native(), &mut raw_coordinate)
254 })?;
255 Ok(LatLng::from_native(raw_coordinate))
256}
257
258pub fn network_status() -> Result<NetworkStatus> {
260 maplibre_core::network_status()
261}
262
263pub fn set_network_status(status: NetworkStatus) -> Result<()> {
265 maplibre_core::set_network_status(status)
266}
267
268#[cfg(test)]
269fn set_network_status_raw(raw_status: u32) -> Result<()> {
270 maplibre_core::set_network_status_raw(raw_status)
271}
272
273#[cfg(test)]
274mod tests {
275 use static_assertions::assert_not_impl_any;
276
277 use super::*;
278
279 assert_not_impl_any!(RuntimeHandle: Send, Sync);
280 assert_not_impl_any!(MapHandle: Send, Sync);
281 assert_not_impl_any!(MapProjectionHandle: Send, Sync);
282 assert_not_impl_any!(NativePointer: Send, Sync);
283 assert_not_impl_any!(FrameNativePointer<'static>: Send, Sync);
284 assert_not_impl_any!(RenderSessionHandle: Send, Sync);
285
286 #[test]
287 fn projected_meter_helpers_round_trip() {
289 let coordinate = LatLng::new(45.0, -122.0);
290 let meters = projected_meters_for_lat_lng(coordinate).unwrap();
291 let round_tripped = lat_lng_for_projected_meters(meters).unwrap();
292
293 assert!((round_tripped.latitude - coordinate.latitude).abs() < 1e-9);
294 assert!((round_tripped.longitude - coordinate.longitude).abs() < 1e-9);
295 }
296
297 #[test]
298 fn invalid_network_status_reports_public_error() {
300 let error = set_network_status_raw(999_999).unwrap_err();
301
302 assert_eq!(error.kind(), ErrorKind::InvalidArgument);
303 assert_eq!(error.raw_status(), Some(sys::MLN_STATUS_INVALID_ARGUMENT));
304 assert!(error.diagnostic().contains("network status"));
305 }
306
307 #[test]
308 fn unknown_network_status_is_rejected_before_calling_c() {
310 let error = set_network_status(NetworkStatus::Unknown(999_999)).unwrap_err();
311
312 assert_eq!(error.kind(), ErrorKind::InvalidArgument);
313 assert_eq!(error.raw_status(), None);
314 assert!(error.diagnostic().contains("cannot be set"));
315 }
316}