1use std::ptr;
2
3pub(crate) use maplibre_core::style::{
4 GeoJsonSourceOptionsNativeExt, NativeGeoJsonSourceOptions, NativeStyleImageOptions,
5 NativeTileSourceOptions, NativeTileUrls, StyleImageOptionsNativeExt,
6 TileSourceOptionsNativeExt,
7};
8pub use maplibre_core::{
9 GeoJsonSourceOptions, ImageContent, ImageStretch, LocationIndicatorImageKind,
10 RasterDemEncoding, SourceInfo, SourceType, StyleImage, StyleImageInfo, StyleImageOptions,
11 StyleImageTextFit, StyleLayerInfo, StyleLayerVisibility, StyleTransitionOptions, TileJsonInfo,
12 TileScheme, TileSourceOptions, VectorTileEncoding,
13};
14use maplibre_native_ffi_core as maplibre_core;
15use maplibre_native_ffi_core::ptr::const_ptr_or_null;
16use maplibre_native_ffi_core::query::FeatureStateSelectorNativeExt;
17use maplibre_native_ffi_core::values::lat_lngs_to_native;
18use maplibre_native_ffi_sys as sys;
19
20use crate::custom_geometry::{CanonicalTileId, CustomGeometrySourceState};
21use crate::custom_mvt_vector::CustomMvtVectorSourceState;
22use crate::render::PremultipliedRgba8Image;
23use crate::values::NativeValue;
24use crate::{
25 CustomGeometrySourceOptions, CustomMvtVectorSourceOptions, Error, ErrorKind,
26 FeatureStateSelector, LatLng, LatLngBounds, Result,
27};
28
29impl super::MapHandle {
30 pub fn set_style_url(&self, url: &str) -> Result<()> {
36 let map = self.inner.native()?;
37 let url = maplibre_core::string::c_string(url)?;
38 maplibre_core::check(unsafe { sys::mln_map_set_style_url(map, url.as_ptr()) })?;
41 Ok(())
42 }
43
44 pub fn set_style_json(&self, json: &[u8]) -> Result<()> {
49 let map = self.inner.native()?;
50 let json = maplibre_core::string::buffer_view(json);
51 maplibre_core::check(unsafe { sys::mln_map_set_style_json(map, json) })
55 }
56
57 pub fn set_global_state_property(&self, property_name: &str, value: &[u8]) -> Result<()> {
59 let map = self.inner.native()?;
60 let property_name = maplibre_core::string::string_view(property_name);
61 let value = maplibre_core::string::buffer_view(value);
62 maplibre_core::check(unsafe {
64 sys::mln_map_set_global_state_property(map, property_name.raw(), value)
65 })
66 }
67
68 pub fn get_global_state(&self) -> Result<Vec<u8>> {
70 let map = self.inner.native()?;
71 let mut out = maplibre_core::ptr::OutHandle::<sys::mln_buffer>::new();
72 maplibre_core::check(unsafe { sys::mln_map_get_global_state(map, out.as_mut_ptr()) })?;
74 unsafe { maplibre_core::string::copy_owned_buffer(out.get()) }
76 }
77
78 pub fn set_feature_state(&self, selector: &FeatureStateSelector, state: &[u8]) -> Result<()> {
80 let map = self.inner.native()?;
81 let selector = selector.to_native();
82 let state = maplibre_core::string::buffer_view(state);
83 maplibre_core::check(unsafe {
85 sys::mln_map_set_feature_state(map, selector.as_ptr(), state)
86 })
87 }
88
89 pub fn get_feature_state(&self, selector: &FeatureStateSelector) -> Result<Vec<u8>> {
91 let map = self.inner.native()?;
92 let selector = selector.to_native();
93 let mut out = maplibre_core::ptr::OutHandle::<sys::mln_buffer>::new();
94 maplibre_core::check(unsafe {
96 sys::mln_map_get_feature_state(map, selector.as_ptr(), out.as_mut_ptr())
97 })?;
98 unsafe { maplibre_core::string::copy_owned_buffer(out.get()) }
100 }
101
102 pub fn remove_feature_state(&self, selector: &FeatureStateSelector) -> Result<()> {
104 let map = self.inner.native()?;
105 let selector = selector.to_native();
106 maplibre_core::check(unsafe { sys::mln_map_remove_feature_state(map, selector.as_ptr()) })
108 }
109
110 pub fn loaded_style_json(&self) -> Result<Vec<u8>> {
115 let map = self.inner.native()?;
116 unsafe {
119 copy_bytes(|text, capacity, out_size| {
120 sys::mln_map_copy_loaded_style_json(map, text, capacity, out_size)
121 })
122 }
123 }
124
125 pub fn style_url(&self) -> Result<String> {
132 let map = self.inner.native()?;
133 unsafe {
136 copy_text(|url, capacity, out_size| {
137 sys::mln_map_copy_style_url(map, url, capacity, out_size)
138 })
139 }
140 }
141
142 pub fn add_custom_geometry_source(
150 &self,
151 source_id: &str,
152 options: CustomGeometrySourceOptions,
153 ) -> Result<()> {
154 let map = self.inner.native()?;
155 let source_id_view = maplibre_core::string::string_view(source_id);
156 let state = CustomGeometrySourceState::new(options);
157 let descriptor = state.descriptor();
158 let state = Box::into_raw(state);
161 let status = unsafe {
164 sys::mln_map_add_custom_geometry_source(map, source_id_view.raw(), &descriptor)
165 };
166 if let Err(error) = maplibre_core::check(status) {
167 drop(unsafe { Box::from_raw(state) });
170 return Err(error);
171 }
172 Ok(())
173 }
174
175 pub fn set_custom_geometry_source_tile_data(
177 &self,
178 source_id: &str,
179 tile_id: CanonicalTileId,
180 data: &[u8],
181 ) -> Result<()> {
182 let map = self.inner.native()?;
183 let source_id = maplibre_core::string::string_view(source_id);
184 let data = maplibre_core::string::buffer_view(data);
185 maplibre_core::check(unsafe {
188 sys::mln_map_set_custom_geometry_source_tile_data(
189 map,
190 source_id.raw(),
191 tile_id.to_native(),
192 data,
193 )
194 })
195 }
196
197 pub fn invalidate_custom_geometry_source_tile(
199 &self,
200 source_id: &str,
201 tile_id: CanonicalTileId,
202 ) -> Result<()> {
203 let map = self.inner.native()?;
204 let source_id = maplibre_core::string::string_view(source_id);
205 maplibre_core::check(unsafe {
208 sys::mln_map_invalidate_custom_geometry_source_tile(
209 map,
210 source_id.raw(),
211 tile_id.to_native(),
212 )
213 })
214 }
215
216 pub fn invalidate_custom_geometry_source_region(
218 &self,
219 source_id: &str,
220 bounds: LatLngBounds,
221 ) -> Result<()> {
222 let map = self.inner.native()?;
223 let source_id = maplibre_core::string::string_view(source_id);
224 maplibre_core::check(unsafe {
227 sys::mln_map_invalidate_custom_geometry_source_region(
228 map,
229 source_id.raw(),
230 bounds.to_native(),
231 )
232 })
233 }
234
235 pub fn add_custom_mvt_vector_source(
243 &self,
244 source_id: &str,
245 options: CustomMvtVectorSourceOptions,
246 ) -> Result<()> {
247 let map = self.inner.native()?;
248 let source_id_view = maplibre_core::string::string_view(source_id);
249 let state = CustomMvtVectorSourceState::new(options);
250 let descriptor = state.descriptor();
251 let state = Box::into_raw(state);
254 let status = unsafe {
257 sys::mln_map_add_custom_mvt_vector_source(map, source_id_view.raw(), &descriptor)
258 };
259 if let Err(error) = maplibre_core::check(status) {
260 drop(unsafe { Box::from_raw(state) });
263 return Err(error);
264 }
265 Ok(())
266 }
267
268 pub fn set_custom_mvt_vector_source_tile_data(
273 &self,
274 source_id: &str,
275 tile_id: CanonicalTileId,
276 data: &[u8],
277 ) -> Result<()> {
278 let map = self.inner.native()?;
279 let source_id = maplibre_core::string::string_view(source_id);
280 let data = maplibre_core::string::buffer_view(data);
281 maplibre_core::check(unsafe {
284 sys::mln_map_set_custom_mvt_vector_source_tile_data(
285 map,
286 source_id.raw(),
287 tile_id.to_native(),
288 data,
289 )
290 })
291 }
292
293 pub fn set_custom_mvt_vector_source_tile_error(
295 &self,
296 source_id: &str,
297 tile_id: CanonicalTileId,
298 message: &str,
299 ) -> Result<()> {
300 let map = self.inner.native()?;
301 let source_id = maplibre_core::string::string_view(source_id);
302 let message = maplibre_core::string::string_view(message);
303 maplibre_core::check(unsafe {
306 sys::mln_map_set_custom_mvt_vector_source_tile_error(
307 map,
308 source_id.raw(),
309 tile_id.to_native(),
310 message.raw(),
311 )
312 })
313 }
314
315 pub fn invalidate_custom_mvt_vector_source_tile(
317 &self,
318 source_id: &str,
319 tile_id: CanonicalTileId,
320 ) -> Result<()> {
321 let map = self.inner.native()?;
322 let source_id = maplibre_core::string::string_view(source_id);
323 maplibre_core::check(unsafe {
326 sys::mln_map_invalidate_custom_mvt_vector_source_tile(
327 map,
328 source_id.raw(),
329 tile_id.to_native(),
330 )
331 })
332 }
333
334 pub fn add_style_source_json(&self, source_id: &str, source_json: &[u8]) -> Result<()> {
336 let map = self.inner.native()?;
337 let source_id = maplibre_core::string::string_view(source_id);
338 let source_json = maplibre_core::string::buffer_view(source_json);
339 maplibre_core::check(unsafe {
342 sys::mln_map_add_style_source_json(map, source_id.raw(), source_json)
343 })
344 }
345
346 pub fn add_vector_source_url(
348 &self,
349 source_id: &str,
350 url: &str,
351 options: Option<&TileSourceOptions>,
352 ) -> Result<()> {
353 let map = self.inner.native()?;
354 let source_id = maplibre_core::string::string_view(source_id);
355 let url = maplibre_core::string::string_view(url);
356 let options = options.map(TileSourceOptions::to_native);
357 let options_ptr = options
358 .as_ref()
359 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
360 maplibre_core::check(unsafe {
363 sys::mln_map_add_vector_source_url(map, source_id.raw(), url.raw(), options_ptr)
364 })
365 }
366
367 pub fn add_vector_source_tiles<S: AsRef<str>>(
369 &self,
370 source_id: &str,
371 tiles: &[S],
372 options: Option<&TileSourceOptions>,
373 ) -> Result<()> {
374 let map = self.inner.native()?;
375 let source_id = maplibre_core::string::string_view(source_id);
376 let raw_tiles = NativeTileUrls::new(tiles);
377 let options = options.map(TileSourceOptions::to_native);
378 let options_ptr = options
379 .as_ref()
380 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
381 maplibre_core::check(unsafe {
385 sys::mln_map_add_vector_source_tiles(
386 map,
387 source_id.raw(),
388 raw_tiles.as_ptr(),
389 raw_tiles.len(),
390 options_ptr,
391 )
392 })
393 }
394
395 pub fn add_raster_source_url(
397 &self,
398 source_id: &str,
399 url: &str,
400 options: Option<&TileSourceOptions>,
401 ) -> Result<()> {
402 let map = self.inner.native()?;
403 let source_id = maplibre_core::string::string_view(source_id);
404 let url = maplibre_core::string::string_view(url);
405 let options = options.map(TileSourceOptions::to_native);
406 let options_ptr = options
407 .as_ref()
408 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
409 maplibre_core::check(unsafe {
412 sys::mln_map_add_raster_source_url(map, source_id.raw(), url.raw(), options_ptr)
413 })
414 }
415
416 pub fn add_raster_source_tiles<S: AsRef<str>>(
418 &self,
419 source_id: &str,
420 tiles: &[S],
421 options: Option<&TileSourceOptions>,
422 ) -> Result<()> {
423 let map = self.inner.native()?;
424 let source_id = maplibre_core::string::string_view(source_id);
425 let raw_tiles = NativeTileUrls::new(tiles);
426 let options = options.map(TileSourceOptions::to_native);
427 let options_ptr = options
428 .as_ref()
429 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
430 maplibre_core::check(unsafe {
434 sys::mln_map_add_raster_source_tiles(
435 map,
436 source_id.raw(),
437 raw_tiles.as_ptr(),
438 raw_tiles.len(),
439 options_ptr,
440 )
441 })
442 }
443
444 pub fn add_raster_dem_source_url(
446 &self,
447 source_id: &str,
448 url: &str,
449 options: Option<&TileSourceOptions>,
450 ) -> Result<()> {
451 let map = self.inner.native()?;
452 let source_id = maplibre_core::string::string_view(source_id);
453 let url = maplibre_core::string::string_view(url);
454 let options = options.map(TileSourceOptions::to_native);
455 let options_ptr = options
456 .as_ref()
457 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
458 maplibre_core::check(unsafe {
461 sys::mln_map_add_raster_dem_source_url(map, source_id.raw(), url.raw(), options_ptr)
462 })
463 }
464
465 pub fn add_raster_dem_source_tiles<S: AsRef<str>>(
467 &self,
468 source_id: &str,
469 tiles: &[S],
470 options: Option<&TileSourceOptions>,
471 ) -> Result<()> {
472 let map = self.inner.native()?;
473 let source_id = maplibre_core::string::string_view(source_id);
474 let raw_tiles = NativeTileUrls::new(tiles);
475 let options = options.map(TileSourceOptions::to_native);
476 let options_ptr = options
477 .as_ref()
478 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
479 maplibre_core::check(unsafe {
483 sys::mln_map_add_raster_dem_source_tiles(
484 map,
485 source_id.raw(),
486 raw_tiles.as_ptr(),
487 raw_tiles.len(),
488 options_ptr,
489 )
490 })
491 }
492
493 pub fn add_image_source_url(
499 &self,
500 source_id: &str,
501 coordinates: &[LatLng; 4],
502 url: &str,
503 ) -> Result<()> {
504 let map = self.inner.native()?;
505 let source_id = maplibre_core::string::string_view(source_id);
506 let coordinates = lat_lngs_to_native(coordinates);
507 let url = maplibre_core::string::string_view(url);
508 maplibre_core::check(unsafe {
512 sys::mln_map_add_image_source_url(
513 map,
514 source_id.raw(),
515 const_ptr_or_null(&coordinates),
516 coordinates.len(),
517 url.raw(),
518 )
519 })
520 }
521
522 pub fn add_image_source_image(
528 &self,
529 source_id: &str,
530 coordinates: &[LatLng; 4],
531 image: &PremultipliedRgba8Image,
532 ) -> Result<()> {
533 let map = self.inner.native()?;
534 let source_id = maplibre_core::string::string_view(source_id);
535 let coordinates = lat_lngs_to_native(coordinates);
536 let image = maplibre_core::values::premultiplied_rgba8_image_to_native(image);
537 maplibre_core::check(unsafe {
541 sys::mln_map_add_image_source_image(
542 map,
543 source_id.raw(),
544 const_ptr_or_null(&coordinates),
545 coordinates.len(),
546 &image,
547 )
548 })
549 }
550
551 pub fn set_image_source_url(&self, source_id: &str, url: &str) -> Result<()> {
553 let map = self.inner.native()?;
554 let source_id = maplibre_core::string::string_view(source_id);
555 let url = maplibre_core::string::string_view(url);
556 maplibre_core::check(unsafe {
559 sys::mln_map_set_image_source_url(map, source_id.raw(), url.raw())
560 })
561 }
562
563 pub fn set_image_source_image(
565 &self,
566 source_id: &str,
567 image: &PremultipliedRgba8Image,
568 ) -> Result<()> {
569 let map = self.inner.native()?;
570 let source_id = maplibre_core::string::string_view(source_id);
571 let image = maplibre_core::values::premultiplied_rgba8_image_to_native(image);
572 maplibre_core::check(unsafe {
575 sys::mln_map_set_image_source_image(map, source_id.raw(), &image)
576 })
577 }
578
579 pub fn set_image_source_coordinates(
585 &self,
586 source_id: &str,
587 coordinates: &[LatLng; 4],
588 ) -> Result<()> {
589 let map = self.inner.native()?;
590 let source_id = maplibre_core::string::string_view(source_id);
591 let coordinates = lat_lngs_to_native(coordinates);
592 maplibre_core::check(unsafe {
596 sys::mln_map_set_image_source_coordinates(
597 map,
598 source_id.raw(),
599 const_ptr_or_null(&coordinates),
600 coordinates.len(),
601 )
602 })
603 }
604
605 pub fn image_source_coordinates(&self, source_id: &str) -> Result<Option<[LatLng; 4]>> {
607 let map = self.inner.native()?;
608 let source_id = maplibre_core::string::string_view(source_id);
609 let mut coordinates = [sys::mln_lat_lng {
610 latitude: 0.0,
611 longitude: 0.0,
612 }; 4];
613 let mut coordinate_count = 0;
614 let mut found = false;
615 maplibre_core::check(unsafe {
619 sys::mln_map_get_image_source_coordinates(
620 map,
621 source_id.raw(),
622 coordinates.as_mut_ptr(),
623 coordinates.len(),
624 &mut coordinate_count,
625 &mut found,
626 )
627 })?;
628 if !found {
629 return Ok(None);
630 }
631 if coordinate_count != coordinates.len() {
632 return Err(Error::new(
633 ErrorKind::NativeError,
634 None,
635 "native image source coordinate count did not match Rust image source invariant",
636 ));
637 }
638 Ok(Some(coordinates.map(LatLng::from_native)))
639 }
640
641 pub fn remove_style_source(&self, source_id: &str) -> Result<bool> {
646 let map = self.inner.native()?;
647 let source_id = maplibre_core::string::string_view(source_id);
648 let mut removed = false;
649 maplibre_core::check(unsafe {
652 sys::mln_map_remove_style_source(map, source_id.raw(), &mut removed)
653 })?;
654 Ok(removed)
655 }
656
657 pub fn style_source_exists(&self, source_id: &str) -> Result<bool> {
659 let map = self.inner.native()?;
660 let source_id = maplibre_core::string::string_view(source_id);
661 let mut exists = false;
662 maplibre_core::check(unsafe {
665 sys::mln_map_style_source_exists(map, source_id.raw(), &mut exists)
666 })?;
667 Ok(exists)
668 }
669
670 pub fn set_style_image(
672 &self,
673 image_id: &str,
674 image: &PremultipliedRgba8Image,
675 options: Option<&StyleImageOptions>,
676 ) -> Result<()> {
677 let map = self.inner.native()?;
678 let image_id = maplibre_core::string::string_view(image_id);
679 let image = maplibre_core::values::premultiplied_rgba8_image_to_native(image);
680 let options = options.map(StyleImageOptions::to_native);
681 let options_ptr = options
682 .as_ref()
683 .map_or(ptr::null(), NativeStyleImageOptions::as_ptr);
684 maplibre_core::check(unsafe {
688 sys::mln_map_set_style_image(map, image_id.raw(), &image, options_ptr)
689 })
690 }
691
692 pub fn remove_style_image(&self, image_id: &str) -> Result<bool> {
696 let map = self.inner.native()?;
697 let image_id = maplibre_core::string::string_view(image_id);
698 let mut removed = false;
699 maplibre_core::check(unsafe {
702 sys::mln_map_remove_style_image(map, image_id.raw(), &mut removed)
703 })?;
704 Ok(removed)
705 }
706
707 pub fn style_image_exists(&self, image_id: &str) -> Result<bool> {
709 let map = self.inner.native()?;
710 let image_id = maplibre_core::string::string_view(image_id);
711 let mut exists = false;
712 maplibre_core::check(unsafe {
715 sys::mln_map_style_image_exists(map, image_id.raw(), &mut exists)
716 })?;
717 Ok(exists)
718 }
719
720 pub fn style_image_info(&self, image_id: &str) -> Result<Option<StyleImageInfo>> {
722 let map = self.inner.native()?;
723 let image_id = maplibre_core::string::string_view(image_id);
724 let mut info = maplibre_core::style::empty_style_image_info();
725 let mut found = false;
726 maplibre_core::check(unsafe {
730 sys::mln_map_get_style_image_info(map, image_id.raw(), &mut info, &mut found)
731 })?;
732 Ok(found.then(|| maplibre_core::values::style_image_info_from_native(&info)))
733 }
734
735 pub fn copy_style_image_premultiplied_rgba8(
737 &self,
738 image_id: &str,
739 ) -> Result<Option<StyleImage>> {
740 let map = self.inner.native()?;
741 let image_id = maplibre_core::string::string_view(image_id);
742 let mut raw_info = maplibre_core::style::empty_style_image_info();
743 let mut info_found = false;
744 maplibre_core::check(unsafe {
748 sys::mln_map_get_style_image_info(map, image_id.raw(), &mut raw_info, &mut info_found)
749 })?;
750 if !info_found {
751 return Ok(None);
752 }
753 let info = maplibre_core::values::style_image_info_from_native(&raw_info);
754
755 let mut data = vec![0u8; info.byte_length];
756 let mut copied_size = 0;
757 let mut found = false;
758 let pixels = if data.is_empty() {
759 ptr::null_mut()
760 } else {
761 data.as_mut_ptr()
762 };
763 maplibre_core::check(unsafe {
767 sys::mln_map_copy_style_image_premultiplied_rgba8(
768 map,
769 image_id.raw(),
770 pixels,
771 data.len(),
772 &mut copied_size,
773 &mut found,
774 )
775 })?;
776 if !found {
777 return Ok(None);
778 }
779 maplibre_core::style::style_image_from_copied_premultiplied_rgba8(info, data, copied_size)
780 .map(Some)
781 }
782
783 pub fn style_source_type(&self, source_id: &str) -> Result<Option<SourceType>> {
785 let map = self.inner.native()?;
786 let source_id = maplibre_core::string::string_view(source_id);
787 let mut raw_source_type = sys::MLN_STYLE_SOURCE_TYPE_UNKNOWN;
788 let mut found = false;
789 maplibre_core::check(unsafe {
792 sys::mln_map_get_style_source_type(
793 map,
794 source_id.raw(),
795 &mut raw_source_type,
796 &mut found,
797 )
798 })?;
799 Ok(found.then(|| SourceType::from_raw(raw_source_type)))
800 }
801
802 pub fn style_source_info(&self, source_id: &str) -> Result<Option<SourceInfo>> {
804 let map = self.inner.native()?;
805 let source_id = maplibre_core::string::string_view(source_id);
806 let mut info = maplibre_core::style::empty_style_source_info();
807 let mut found = false;
808 maplibre_core::check(unsafe {
812 sys::mln_map_get_style_source_info(map, source_id.raw(), &mut info, &mut found)
813 })?;
814 if !found {
815 return Ok(None);
816 }
817
818 let attribution = if info.has_attribution {
819 match self.copy_style_source_attribution(map, source_id.raw(), info.attribution_size)? {
820 Some(attribution) => Some(attribution),
821 None => return Ok(None),
822 }
823 } else {
824 None
825 };
826
827 let url = if info.fields & sys::MLN_STYLE_SOURCE_INFO_URL != 0 {
828 match self.copy_style_source_url(map, source_id.raw(), info.url_size)? {
829 Some(url) => Some(url),
830 None => return Ok(None),
831 }
832 } else {
833 None
834 };
835
836 let tiles = if info.fields & sys::MLN_STYLE_SOURCE_INFO_TILEJSON != 0 {
837 match self.copy_style_source_tile_urls(map, source_id.raw())? {
838 Some(tiles) => tiles,
839 None => return Ok(None),
840 }
841 } else {
842 Vec::new()
843 };
844
845 Ok(Some(maplibre_core::style::style_source_info_from_native(
846 &info,
847 attribution,
848 url,
849 tiles,
850 )))
851 }
852
853 pub fn set_style_source_volatile(&self, source_id: &str, is_volatile: bool) -> Result<()> {
859 let map = self.inner.native()?;
860 let source_id = maplibre_core::string::string_view(source_id);
861 maplibre_core::check(unsafe {
864 sys::mln_map_set_style_source_volatile(map, source_id.raw(), is_volatile)
865 })
866 }
867
868 fn copy_style_source_attribution(
869 &self,
870 map: sys::mln_map,
871 source_id: sys::mln_buffer_view,
872 attribution_size: usize,
873 ) -> Result<Option<String>> {
874 if attribution_size == 0 {
875 let mut copied_size = 0;
876 let mut found = false;
877 maplibre_core::check(unsafe {
881 sys::mln_map_copy_style_source_attribution(
882 map,
883 source_id,
884 ptr::null_mut(),
885 0,
886 &mut copied_size,
887 &mut found,
888 )
889 })?;
890 return Ok(found.then(String::new));
891 }
892
893 let mut buffer = vec![0u8; attribution_size];
894 let mut copied_size = 0;
895 let mut found = false;
896 maplibre_core::check(unsafe {
900 sys::mln_map_copy_style_source_attribution(
901 map,
902 source_id,
903 buffer.as_mut_ptr().cast(),
904 buffer.len(),
905 &mut copied_size,
906 &mut found,
907 )
908 })?;
909 if !found {
910 return Ok(None);
911 }
912 if copied_size > buffer.len() {
913 return Err(Error::new(
914 ErrorKind::NativeError,
915 None,
916 "native style source attribution size exceeded caller buffer",
917 ));
918 }
919 buffer.truncate(copied_size);
920 String::from_utf8(buffer).map(Some).map_err(|error| {
921 Error::invalid_argument(format!(
922 "native style source attribution was not valid UTF-8: {error}"
923 ))
924 })
925 }
926
927 fn copy_style_source_url(
928 &self,
929 map: sys::mln_map,
930 source_id: sys::mln_buffer_view,
931 url_size: usize,
932 ) -> Result<Option<String>> {
933 let mut buffer = vec![0u8; url_size];
934 let mut copied_size = 0;
935 let mut found = false;
936 maplibre_core::check(unsafe {
940 sys::mln_map_copy_style_source_url(
941 map,
942 source_id,
943 if buffer.is_empty() {
944 ptr::null_mut()
945 } else {
946 buffer.as_mut_ptr().cast()
947 },
948 buffer.len(),
949 &mut copied_size,
950 &mut found,
951 )
952 })?;
953 if !found {
954 return Ok(None);
955 }
956 if copied_size > buffer.len() {
957 return Err(Error::new(
958 ErrorKind::NativeError,
959 None,
960 "native style source URL size exceeded caller buffer",
961 ));
962 }
963 buffer.truncate(copied_size);
964 String::from_utf8(buffer).map(Some).map_err(|error| {
965 Error::invalid_argument(format!(
966 "native style source URL was not valid UTF-8: {error}"
967 ))
968 })
969 }
970
971 fn copy_style_source_tile_urls(
972 &self,
973 map: sys::mln_map,
974 source_id: sys::mln_buffer_view,
975 ) -> Result<Option<Vec<String>>> {
976 let mut out = maplibre_core::ptr::OutHandle::<sys::mln_style_string_list>::new();
977 let mut found = false;
978 maplibre_core::check(unsafe {
981 sys::mln_map_get_style_source_tile_urls(map, source_id, out.as_mut_ptr(), &mut found)
982 })?;
983 if !found {
984 return Ok(None);
985 }
986 unsafe {
989 maplibre_core::style::copy_style_string_list(out.into_live("mln_style_string_list")?)
990 .map(Some)
991 }
992 }
993
994 pub fn add_geojson_source_url(
997 &self,
998 source_id: &str,
999 url: &str,
1000 options: Option<&GeoJsonSourceOptions>,
1001 ) -> Result<()> {
1002 let map = self.inner.native()?;
1003 let source_id = maplibre_core::string::string_view(source_id);
1004 let url = maplibre_core::string::string_view(url);
1005 let options = options
1006 .map(GeoJsonSourceOptions::try_to_native)
1007 .transpose()?;
1008 let options_ptr = options
1009 .as_ref()
1010 .map_or(ptr::null(), NativeGeoJsonSourceOptions::as_ptr);
1011 maplibre_core::check(unsafe {
1015 sys::mln_map_add_geojson_source_url(map, source_id.raw(), url.raw(), options_ptr)
1016 })
1017 }
1018
1019 pub fn add_geojson_source_data(
1024 &self,
1025 source_id: &str,
1026 data: &crate::GeoJsonSourceDataHandle,
1027 ) -> Result<()> {
1028 let map = self.inner.native()?;
1029 let source_id = maplibre_core::string::string_view(source_id);
1030 maplibre_core::check(unsafe {
1033 sys::mln_map_add_geojson_source_data(map, source_id.raw(), data.native())
1034 })
1035 }
1036
1037 pub fn set_geojson_source_url(&self, source_id: &str, url: &str) -> Result<()> {
1041 let map = self.inner.native()?;
1042 let source_id = maplibre_core::string::string_view(source_id);
1043 let url = maplibre_core::string::string_view(url);
1044 maplibre_core::check(unsafe {
1046 sys::mln_map_set_geojson_source_url(map, source_id.raw(), url.raw())
1047 })
1048 }
1049
1050 pub fn set_geojson_source_data(
1057 &self,
1058 source_id: &str,
1059 data: &crate::GeoJsonSourceDataHandle,
1060 ) -> Result<()> {
1061 let map = self.inner.native()?;
1062 let source_id = maplibre_core::string::string_view(source_id);
1063 maplibre_core::check(unsafe {
1066 sys::mln_map_set_geojson_source_data(map, source_id.raw(), data.native())
1067 })
1068 }
1069
1070 pub fn set_geojson_source_synchronous_tiling(
1077 &self,
1078 source_id: &str,
1079 enabled: bool,
1080 ) -> Result<()> {
1081 let map = self.inner.native()?;
1082 let source_id = maplibre_core::string::string_view(source_id);
1083 maplibre_core::check(unsafe {
1085 sys::mln_map_set_geojson_source_synchronous_tiling(map, source_id.raw(), enabled)
1086 })
1087 }
1088
1089 pub fn add_style_layer_json(
1091 &self,
1092 layer_json: &[u8],
1093 before_layer_id: Option<&str>,
1094 ) -> Result<()> {
1095 let map = self.inner.native()?;
1096 let layer_json = maplibre_core::string::buffer_view(layer_json);
1097 let before_layer_id = maplibre_core::string::string_view(before_layer_id.unwrap_or(""));
1098 maplibre_core::check(unsafe {
1101 sys::mln_map_add_style_layer_json(map, layer_json, before_layer_id.raw())
1102 })
1103 }
1104
1105 pub fn add_hillshade_layer(
1107 &self,
1108 layer_id: &str,
1109 source_id: &str,
1110 before_layer_id: Option<&str>,
1111 ) -> Result<()> {
1112 let map = self.inner.native()?;
1113 let layer_id = maplibre_core::string::string_view(layer_id);
1114 let source_id = maplibre_core::string::string_view(source_id);
1115 let before_layer_id = maplibre_core::string::string_view(before_layer_id.unwrap_or(""));
1116 maplibre_core::check(unsafe {
1118 sys::mln_map_add_hillshade_layer(
1119 map,
1120 layer_id.raw(),
1121 source_id.raw(),
1122 before_layer_id.raw(),
1123 )
1124 })
1125 }
1126
1127 pub fn add_color_relief_layer(
1129 &self,
1130 layer_id: &str,
1131 source_id: &str,
1132 before_layer_id: Option<&str>,
1133 ) -> Result<()> {
1134 let map = self.inner.native()?;
1135 let layer_id = maplibre_core::string::string_view(layer_id);
1136 let source_id = maplibre_core::string::string_view(source_id);
1137 let before_layer_id = maplibre_core::string::string_view(before_layer_id.unwrap_or(""));
1138 maplibre_core::check(unsafe {
1140 sys::mln_map_add_color_relief_layer(
1141 map,
1142 layer_id.raw(),
1143 source_id.raw(),
1144 before_layer_id.raw(),
1145 )
1146 })
1147 }
1148
1149 pub fn add_location_indicator_layer(
1151 &self,
1152 layer_id: &str,
1153 before_layer_id: Option<&str>,
1154 ) -> Result<()> {
1155 let map = self.inner.native()?;
1156 let layer_id = maplibre_core::string::string_view(layer_id);
1157 let before_layer_id = maplibre_core::string::string_view(before_layer_id.unwrap_or(""));
1158 maplibre_core::check(unsafe {
1160 sys::mln_map_add_location_indicator_layer(map, layer_id.raw(), before_layer_id.raw())
1161 })
1162 }
1163
1164 pub fn set_location_indicator_location(
1166 &self,
1167 layer_id: &str,
1168 coordinate: LatLng,
1169 altitude: f64,
1170 ) -> Result<()> {
1171 let map = self.inner.native()?;
1172 let layer_id = maplibre_core::string::string_view(layer_id);
1173 maplibre_core::check(unsafe {
1176 sys::mln_map_set_location_indicator_location(
1177 map,
1178 layer_id.raw(),
1179 coordinate.to_native(),
1180 altitude,
1181 )
1182 })
1183 }
1184
1185 pub fn set_location_indicator_bearing(&self, layer_id: &str, bearing: f64) -> Result<()> {
1187 let map = self.inner.native()?;
1188 let layer_id = maplibre_core::string::string_view(layer_id);
1189 maplibre_core::check(unsafe {
1191 sys::mln_map_set_location_indicator_bearing(map, layer_id.raw(), bearing)
1192 })
1193 }
1194
1195 pub fn set_location_indicator_accuracy_radius(
1197 &self,
1198 layer_id: &str,
1199 radius: f64,
1200 ) -> Result<()> {
1201 let map = self.inner.native()?;
1202 let layer_id = maplibre_core::string::string_view(layer_id);
1203 maplibre_core::check(unsafe {
1205 sys::mln_map_set_location_indicator_accuracy_radius(map, layer_id.raw(), radius)
1206 })
1207 }
1208
1209 pub fn set_location_indicator_image_name(
1211 &self,
1212 layer_id: &str,
1213 image_kind: LocationIndicatorImageKind,
1214 image_id: &str,
1215 ) -> Result<()> {
1216 let map = self.inner.native()?;
1217 let layer_id = maplibre_core::string::string_view(layer_id);
1218 let image_id = maplibre_core::string::string_view(image_id);
1219 maplibre_core::check(unsafe {
1222 sys::mln_map_set_location_indicator_image_name(
1223 map,
1224 layer_id.raw(),
1225 image_kind.raw_value(),
1226 image_id.raw(),
1227 )
1228 })
1229 }
1230
1231 pub fn style_layer_json(&self, layer_id: &str) -> Result<Option<Vec<u8>>> {
1233 let map = self.inner.native()?;
1234 let layer_id = maplibre_core::string::string_view(layer_id);
1235 let mut out = maplibre_core::ptr::OutHandle::<sys::mln_buffer>::new();
1236 let mut found = false;
1237 maplibre_core::check(unsafe {
1240 sys::mln_map_get_style_layer_json(map, layer_id.raw(), out.as_mut_ptr(), &mut found)
1241 })?;
1242 if !found {
1243 return Ok(None);
1244 }
1245 unsafe { maplibre_core::string::copy_owned_buffer(out.get()) }.map(Some)
1247 }
1248
1249 pub fn set_style_light_json(&self, light_json: &[u8]) -> Result<()> {
1251 let map = self.inner.native()?;
1252 let light_json = maplibre_core::string::buffer_view(light_json);
1253 maplibre_core::check(unsafe { sys::mln_map_set_style_light_json(map, light_json) })
1255 }
1256
1257 pub fn set_style_light_property(&self, property_name: &str, value: &[u8]) -> Result<()> {
1259 let map = self.inner.native()?;
1260 let property_name = maplibre_core::string::string_view(property_name);
1261 let value = maplibre_core::string::buffer_view(value);
1262 maplibre_core::check(unsafe {
1264 sys::mln_map_set_style_light_property(map, property_name.raw(), value)
1265 })
1266 }
1267
1268 pub fn style_light_property(&self, property_name: &str) -> Result<Option<Vec<u8>>> {
1270 let map = self.inner.native()?;
1271 let property_name = maplibre_core::string::string_view(property_name);
1272 let mut out = maplibre_core::ptr::OutHandle::<sys::mln_buffer>::new();
1273 maplibre_core::check(unsafe {
1276 sys::mln_map_get_style_light_property(map, property_name.raw(), out.as_mut_ptr())
1277 })?;
1278 let Some(buffer) = out.into_option() else {
1279 return Ok(None);
1280 };
1281 unsafe { maplibre_core::string::copy_owned_buffer(buffer) }.map(Some)
1283 }
1284
1285 pub fn set_style_transition_options(&self, options: &StyleTransitionOptions) -> Result<()> {
1289 let map = self.inner.native()?;
1290 let raw = maplibre_core::style::style_transition_options_to_native(options);
1291 maplibre_core::check(unsafe { sys::mln_map_set_style_transition_options(map, &raw) })
1294 }
1295
1296 pub fn style_transition_options(&self) -> Result<StyleTransitionOptions> {
1298 let map = self.inner.native()?;
1299 let mut raw = maplibre_core::style::empty_style_transition_options();
1300 maplibre_core::check(unsafe { sys::mln_map_get_style_transition_options(map, &mut raw) })?;
1302 Ok(maplibre_core::style::style_transition_options_from_native(
1303 &raw,
1304 ))
1305 }
1306
1307 pub fn set_layer_property(
1309 &self,
1310 layer_id: &str,
1311 property_name: &str,
1312 value: &[u8],
1313 ) -> Result<()> {
1314 let map = self.inner.native()?;
1315 let layer_id = maplibre_core::string::string_view(layer_id);
1316 let property_name = maplibre_core::string::string_view(property_name);
1317 let value = maplibre_core::string::buffer_view(value);
1318 maplibre_core::check(unsafe {
1321 sys::mln_map_set_layer_property(map, layer_id.raw(), property_name.raw(), value)
1322 })
1323 }
1324
1325 pub fn layer_property(&self, layer_id: &str, property_name: &str) -> Result<Option<Vec<u8>>> {
1327 let map = self.inner.native()?;
1328 let layer_id = maplibre_core::string::string_view(layer_id);
1329 let property_name = maplibre_core::string::string_view(property_name);
1330 let mut out = maplibre_core::ptr::OutHandle::<sys::mln_buffer>::new();
1331 maplibre_core::check(unsafe {
1334 sys::mln_map_get_layer_property(
1335 map,
1336 layer_id.raw(),
1337 property_name.raw(),
1338 out.as_mut_ptr(),
1339 )
1340 })?;
1341 let Some(buffer) = out.into_option() else {
1342 return Ok(None);
1343 };
1344 unsafe { maplibre_core::string::copy_owned_buffer(buffer) }.map(Some)
1346 }
1347
1348 pub fn set_layer_filter(&self, layer_id: &str, filter: Option<&[u8]>) -> Result<()> {
1350 let map = self.inner.native()?;
1351 let layer_id = maplibre_core::string::string_view(layer_id);
1352 let native_filter = filter.map(maplibre_core::string::buffer_view);
1353 maplibre_core::check(unsafe {
1356 sys::mln_map_set_layer_filter(
1357 map,
1358 layer_id.raw(),
1359 native_filter.as_ref().map_or(ptr::null(), ptr::from_ref),
1360 )
1361 })
1362 }
1363
1364 pub fn layer_filter(&self, layer_id: &str) -> Result<Option<Vec<u8>>> {
1366 let map = self.inner.native()?;
1367 let layer_id = maplibre_core::string::string_view(layer_id);
1368 let mut out = maplibre_core::ptr::OutHandle::<sys::mln_buffer>::new();
1369 maplibre_core::check(unsafe {
1372 sys::mln_map_get_layer_filter(map, layer_id.raw(), out.as_mut_ptr())
1373 })?;
1374 let Some(buffer) = out.into_option() else {
1375 return Ok(None);
1376 };
1377 unsafe { maplibre_core::string::copy_owned_buffer(buffer) }.map(Some)
1379 }
1380
1381 pub fn style_image_stretches(
1385 &self,
1386 image_id: &str,
1387 ) -> Result<Option<(Vec<ImageStretch>, Vec<ImageStretch>)>> {
1388 let map = self.inner.native()?;
1389 let image_id = maplibre_core::string::string_view(image_id);
1390 let mut x_count = 0;
1391 let mut y_count = 0;
1392 let mut found = false;
1393 maplibre_core::check(unsafe {
1397 sys::mln_map_copy_style_image_stretches(
1398 map,
1399 image_id.raw(),
1400 ptr::null_mut(),
1401 0,
1402 &mut x_count,
1403 ptr::null_mut(),
1404 0,
1405 &mut y_count,
1406 &mut found,
1407 )
1408 })?;
1409 if !found {
1410 return Ok(None);
1411 }
1412
1413 let mut stretch_x = vec![sys::mln_image_stretch { from: 0.0, to: 0.0 }; x_count];
1414 let mut stretch_y = vec![sys::mln_image_stretch { from: 0.0, to: 0.0 }; y_count];
1415 maplibre_core::check(unsafe {
1418 sys::mln_map_copy_style_image_stretches(
1419 map,
1420 image_id.raw(),
1421 stretch_x.as_mut_ptr(),
1422 stretch_x.len(),
1423 &mut x_count,
1424 stretch_y.as_mut_ptr(),
1425 stretch_y.len(),
1426 &mut y_count,
1427 &mut found,
1428 )
1429 })?;
1430 let to_public = |stretches: &[sys::mln_image_stretch]| -> Vec<ImageStretch> {
1431 stretches
1432 .iter()
1433 .map(|stretch| ImageStretch::new(stretch.from, stretch.to))
1434 .collect()
1435 };
1436 Ok(Some((to_public(&stretch_x), to_public(&stretch_y))))
1437 }
1438
1439 pub fn set_layer_source_layer(&self, layer_id: &str, source_layer: &str) -> Result<()> {
1443 let map = self.inner.native()?;
1444 let layer_id = maplibre_core::string::string_view(layer_id);
1445 let source_layer = maplibre_core::string::string_view(source_layer);
1446 maplibre_core::check(unsafe {
1448 sys::mln_map_set_layer_source_layer(map, layer_id.raw(), source_layer.raw())
1449 })
1450 }
1451
1452 pub fn layer_source_layer(&self, layer_id: &str) -> Result<String> {
1454 let map = self.inner.native()?;
1455 let layer_id = maplibre_core::string::string_view(layer_id);
1456 unsafe {
1459 copy_text(|text, capacity, out_size| {
1460 sys::mln_map_copy_layer_source_layer(map, layer_id.raw(), text, capacity, out_size)
1461 })
1462 }
1463 }
1464
1465 pub fn set_layer_source_id(&self, layer_id: &str, source_id: &str) -> Result<()> {
1470 let map = self.inner.native()?;
1471 let layer_id = maplibre_core::string::string_view(layer_id);
1472 let source_id = maplibre_core::string::string_view(source_id);
1473 maplibre_core::check(unsafe {
1475 sys::mln_map_set_layer_source_id(map, layer_id.raw(), source_id.raw())
1476 })
1477 }
1478
1479 pub fn layer_source_id(&self, layer_id: &str) -> Result<String> {
1481 let map = self.inner.native()?;
1482 let layer_id = maplibre_core::string::string_view(layer_id);
1483 unsafe {
1486 copy_text(|text, capacity, out_size| {
1487 sys::mln_map_copy_layer_source_id(map, layer_id.raw(), text, capacity, out_size)
1488 })
1489 }
1490 }
1491
1492 pub fn set_layer_min_zoom(&self, layer_id: &str, min_zoom: f64) -> Result<()> {
1496 let map = self.inner.native()?;
1497 let layer_id = maplibre_core::string::string_view(layer_id);
1498 maplibre_core::check(unsafe {
1500 sys::mln_map_set_layer_min_zoom(map, layer_id.raw(), min_zoom)
1501 })
1502 }
1503
1504 pub fn layer_min_zoom(&self, layer_id: &str) -> Result<f64> {
1508 let map = self.inner.native()?;
1509 let layer_id = maplibre_core::string::string_view(layer_id);
1510 let mut min_zoom = 0.0;
1511 maplibre_core::check(unsafe {
1514 sys::mln_map_get_layer_min_zoom(map, layer_id.raw(), &mut min_zoom)
1515 })?;
1516 Ok(min_zoom)
1517 }
1518
1519 pub fn set_layer_max_zoom(&self, layer_id: &str, max_zoom: f64) -> Result<()> {
1523 let map = self.inner.native()?;
1524 let layer_id = maplibre_core::string::string_view(layer_id);
1525 maplibre_core::check(unsafe {
1527 sys::mln_map_set_layer_max_zoom(map, layer_id.raw(), max_zoom)
1528 })
1529 }
1530
1531 pub fn layer_max_zoom(&self, layer_id: &str) -> Result<f64> {
1535 let map = self.inner.native()?;
1536 let layer_id = maplibre_core::string::string_view(layer_id);
1537 let mut max_zoom = 0.0;
1538 maplibre_core::check(unsafe {
1541 sys::mln_map_get_layer_max_zoom(map, layer_id.raw(), &mut max_zoom)
1542 })?;
1543 Ok(max_zoom)
1544 }
1545
1546 pub fn set_layer_visibility(
1548 &self,
1549 layer_id: &str,
1550 visibility: StyleLayerVisibility,
1551 ) -> Result<()> {
1552 let map = self.inner.native()?;
1553 let layer_id = maplibre_core::string::string_view(layer_id);
1554 maplibre_core::check(unsafe {
1556 sys::mln_map_set_layer_visibility(map, layer_id.raw(), visibility.raw_value())
1557 })
1558 }
1559
1560 pub fn layer_visibility(&self, layer_id: &str) -> Result<StyleLayerVisibility> {
1562 let map = self.inner.native()?;
1563 let layer_id = maplibre_core::string::string_view(layer_id);
1564 let mut visibility = 0;
1565 maplibre_core::check(unsafe {
1568 sys::mln_map_get_layer_visibility(map, layer_id.raw(), &mut visibility)
1569 })?;
1570 Ok(StyleLayerVisibility::from_raw(visibility))
1571 }
1572
1573 pub fn style_source_ids(&self) -> Result<Vec<String>> {
1575 let map = self.inner.native()?;
1576 let mut out = maplibre_core::ptr::OutHandle::<sys::mln_style_id_list>::new();
1577 maplibre_core::check(unsafe { sys::mln_map_list_style_source_ids(map, out.as_mut_ptr()) })?;
1581 unsafe { maplibre_core::style::copy_style_id_list(out.into_live("mln_style_id_list")?) }
1584 }
1585
1586 pub fn style_layer_ids(&self) -> Result<Vec<String>> {
1588 let map = self.inner.native()?;
1589 let mut out = maplibre_core::ptr::OutHandle::<sys::mln_style_id_list>::new();
1590 maplibre_core::check(unsafe { sys::mln_map_list_style_layer_ids(map, out.as_mut_ptr()) })?;
1594 unsafe { maplibre_core::style::copy_style_id_list(out.into_live("mln_style_id_list")?) }
1597 }
1598
1599 pub fn style_layers(&self) -> Result<Vec<StyleLayerInfo>> {
1602 let map = self.inner.native()?;
1603 let mut out = maplibre_core::ptr::OutHandle::<sys::mln_style_layer_list>::new();
1604 maplibre_core::check(unsafe { sys::mln_map_list_style_layers(map, out.as_mut_ptr()) })?;
1608 unsafe {
1611 maplibre_core::style::copy_style_layer_list(out.into_live("mln_style_layer_list")?)
1612 }
1613 }
1614}
1615
1616unsafe fn copy_text(
1624 copy: impl Fn(*mut std::os::raw::c_char, usize, *mut usize) -> sys::mln_status,
1625) -> Result<String> {
1626 let mut required = 0;
1627 maplibre_core::check(copy(ptr::null_mut(), 0, &mut required))?;
1628 if required == 0 {
1629 return Ok(String::new());
1630 }
1631
1632 let mut buffer = vec![0u8; required];
1633 let mut copied = 0;
1634 maplibre_core::check(copy(buffer.as_mut_ptr().cast(), buffer.len(), &mut copied))?;
1635 if copied > buffer.len() {
1636 return Err(Error::new(
1637 ErrorKind::NativeError,
1638 None,
1639 "native text size exceeded caller buffer",
1640 ));
1641 }
1642 buffer.truncate(copied);
1643 String::from_utf8(buffer).map_err(|_| {
1644 Error::new(
1645 ErrorKind::NativeError,
1646 None,
1647 "native text was not valid UTF-8",
1648 )
1649 })
1650}
1651
1652unsafe fn copy_bytes(
1659 copy: impl Fn(*mut u8, usize, *mut usize) -> sys::mln_status,
1660) -> Result<Vec<u8>> {
1661 let mut required = 0;
1662 maplibre_core::check(copy(ptr::null_mut(), 0, &mut required))?;
1663 if required == 0 {
1664 return Ok(Vec::new());
1665 }
1666
1667 let mut buffer = vec![0u8; required];
1668 let mut copied = 0;
1669 maplibre_core::check(copy(buffer.as_mut_ptr(), buffer.len(), &mut copied))?;
1670 if copied > buffer.len() {
1671 return Err(Error::new(
1672 ErrorKind::NativeError,
1673 None,
1674 "native byte size exceeded caller buffer",
1675 ));
1676 }
1677 buffer.truncate(copied);
1678 Ok(buffer)
1679}