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::{
45 LogRecord, clear_log_callback, restore_default_async_log_severity_mask,
46 set_async_log_severity_mask, set_log_callback,
47};
48pub use map::{
49 LocationIndicatorImageKind, MapHandle, RasterDemEncoding, SourceInfo, SourceType, StyleImage,
50 StyleImageInfo, StyleImageOptions, TileScheme, TileSourceOptions, VectorTileEncoding,
51};
52pub use maplibre_core::{
53 AmbientCacheOperation, ConstrainMode, Error, ErrorKind, LogEvent, LogSeverity, LogSeverityMask,
54 MapDebugOptions, MapMode, MapOptions, MapTileOptions, MapViewportOptions, NetworkStatus,
55 NorthOrientation, OfflineOperationKind, OfflineOperationResultKind, OfflineRegionDownloadState,
56 OpenGLContextProviderMask, RenderBackendMask, RenderMode, ResourceErrorReason, ResourceKind,
57 ResourceLoadingMethod, ResourcePriority, ResourceResponseStatus, ResourceStoragePolicy,
58 ResourceUsage, Result, RuntimeEventType, TileLodMode, TileOperation, ViewportMode,
59};
60pub use projection::MapProjectionHandle;
61pub use render::{
62 DetachedRenderSessionHandle, EglContextDescriptor, FeatureExtensionResult,
63 FeatureStateSelector, FrameNativePointer, FrameOpenGLTextureName,
64 MetalBorrowedTextureDescriptor, MetalContextDescriptor, MetalOwnedTextureDescriptor,
65 MetalOwnedTextureFrame, MetalOwnedTextureFrameHandle, MetalSurfaceDescriptor, NativePointer,
66 OpenGLBorrowedTextureDescriptor, OpenGLContextDescriptor, OpenGLOwnedTextureDescriptor,
67 OpenGLOwnedTextureFrame, OpenGLOwnedTextureFrameHandle, OpenGLSurfaceDescriptor,
68 PremultipliedRgba8Image, QueriedFeature, RenderSessionHandle, RenderTargetExtent,
69 RenderedFeatureQueryOptions, RenderedQueryGeometry, SourceFeatureQueryOptions,
70 TextureImageInfo, VulkanBorrowedTextureDescriptor, VulkanContextDescriptor,
71 VulkanOwnedTextureDescriptor, VulkanOwnedTextureFrame, VulkanOwnedTextureFrameHandle,
72 VulkanSurfaceDescriptor, WglContextDescriptor,
73};
74pub use resource::{
75 ByteRange, ResourceProviderDecision, ResourceRequest, ResourceRequestHandle, ResourceResponse,
76 ResourceTransformRequest,
77};
78pub use runtime::{
79 OfflineOperationHandle, OfflineRegionDefinition, OfflineRegionInfo, RuntimeHandle,
80 RuntimeOptions,
81};
82pub use values::{
83 EdgeInsets, LatLng, LatLngBounds, ProjectedMeters, Quaternion, ScreenBox, ScreenPoint,
84 UnitBezier, Vec3,
85};
86
87#[derive(Debug)]
90pub struct HandleOperationError<T> {
91 error: Error,
92 handle: T,
93}
94
95impl<T> HandleOperationError<T> {
96 pub(crate) fn new(error: Error, handle: T) -> Self {
97 Self { error, handle }
98 }
99
100 pub fn error(&self) -> &Error {
102 &self.error
103 }
104
105 pub fn kind(&self) -> ErrorKind {
107 self.error.kind()
108 }
109
110 pub fn raw_status(&self) -> Option<sys::mln_status> {
112 self.error.raw_status()
113 }
114
115 pub fn diagnostic(&self) -> &str {
117 self.error.diagnostic()
118 }
119
120 pub fn into_error(self) -> Error {
122 self.error
123 }
124
125 pub fn into_handle(self) -> T {
127 self.handle
128 }
129
130 pub fn into_parts(self) -> (Error, T) {
132 (self.error, self.handle)
133 }
134}
135
136impl<T> std::fmt::Display for HandleOperationError<T> {
137 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
138 self.error.fmt(f)
139 }
140}
141
142impl<T: std::fmt::Debug> std::error::Error for HandleOperationError<T> {}
143
144pub fn c_version() -> u32 {
146 unsafe { sys::mln_c_version() }
149}
150
151pub fn supported_render_backends() -> RenderBackendMask {
153 let mask = unsafe { sys::mln_supported_render_backend_mask() };
156 RenderBackendMask::from_bits_retain(mask)
157}
158
159pub fn supported_opengl_context_providers() -> OpenGLContextProviderMask {
161 let mask = unsafe { sys::mln_opengl_supported_context_provider_mask() };
164 OpenGLContextProviderMask::from_bits_retain(mask)
165}
166
167pub fn projected_meters_for_lat_lng(coordinate: LatLng) -> Result<ProjectedMeters> {
169 let mut raw_meters = sys::mln_projected_meters {
170 northing: 0.0,
171 easting: 0.0,
172 };
173 maplibre_core::check(unsafe {
176 sys::mln_projected_meters_for_lat_lng(coordinate.to_native(), &mut raw_meters)
177 })?;
178 Ok(ProjectedMeters::from_native(raw_meters))
179}
180
181pub fn lat_lng_for_projected_meters(meters: ProjectedMeters) -> Result<LatLng> {
183 let mut raw_coordinate = sys::mln_lat_lng {
184 latitude: 0.0,
185 longitude: 0.0,
186 };
187 maplibre_core::check(unsafe {
190 sys::mln_lat_lng_for_projected_meters(meters.to_native(), &mut raw_coordinate)
191 })?;
192 Ok(LatLng::from_native(raw_coordinate))
193}
194
195pub fn network_status() -> Result<NetworkStatus> {
197 let mut raw_status = 0;
198 maplibre_core::check(unsafe { sys::mln_network_status_get(&mut raw_status) })?;
200 Ok(NetworkStatus::from_raw(raw_status))
201}
202
203pub fn set_network_status(status: NetworkStatus) -> Result<()> {
205 set_network_status_raw(status.raw()?)
206}
207
208fn set_network_status_raw(raw_status: u32) -> Result<()> {
209 maplibre_core::check(unsafe { sys::mln_network_status_set(raw_status) })
212}
213
214#[cfg(test)]
215mod tests {
216 use static_assertions::assert_not_impl_any;
217
218 use super::*;
219
220 assert_not_impl_any!(RuntimeHandle: Send, Sync);
221 assert_not_impl_any!(MapHandle: Send, Sync);
222 assert_not_impl_any!(MapProjectionHandle: Send, Sync);
223 assert_not_impl_any!(NativePointer: Send, Sync);
224 assert_not_impl_any!(FrameNativePointer<'static>: Send, Sync);
225 assert_not_impl_any!(RenderSessionHandle: Send, Sync);
226
227 #[test]
228 fn projected_meter_helpers_round_trip() {
229 let coordinate = LatLng::new(45.0, -122.0);
230 let meters = projected_meters_for_lat_lng(coordinate).unwrap();
231 let round_tripped = lat_lng_for_projected_meters(meters).unwrap();
232
233 assert!((round_tripped.latitude - coordinate.latitude).abs() < 1e-9);
234 assert!((round_tripped.longitude - coordinate.longitude).abs() < 1e-9);
235 }
236
237 #[test]
238 fn invalid_network_status_reports_public_error() {
239 let error = set_network_status_raw(999_999).unwrap_err();
240
241 assert_eq!(error.kind(), ErrorKind::InvalidArgument);
242 assert_eq!(error.raw_status(), Some(sys::MLN_STATUS_INVALID_ARGUMENT));
243 assert!(error.diagnostic().contains("network status"));
244 }
245
246 #[test]
247 fn unknown_network_status_is_rejected_before_calling_c() {
248 let error = set_network_status(NetworkStatus::Unknown(999_999)).unwrap_err();
249
250 assert_eq!(error.kind(), ErrorKind::InvalidArgument);
251 assert_eq!(error.raw_status(), None);
252 assert!(error.diagnostic().contains("cannot be set"));
253 }
254}