1#![doc = include_str!("../README.md")]
2#![deny(warnings, missing_debug_implementations, missing_docs)]
3
4use std::fmt;
5
6pub unsafe fn slice_from_raw_parts<'a, T>(ptr: *const T, len: usize) -> &'a [T] {
36 if !ptr.is_null() {
37 std::slice::from_raw_parts(ptr, len)
38 } else {
39 std::slice::from_raw_parts(std::ptr::NonNull::dangling().as_ref(), 0)
40 }
41}
42
43#[derive(Clone, Copy)]
72pub struct Str<'a> {
73 data: &'a [u8],
74}
75
76impl<'a> Str<'a> {
77 pub unsafe fn from_raw_parts(ptr: *const std::os::raw::c_char, len: usize) -> Self {
87 Self {
88 data: slice_from_raw_parts(ptr as *const u8, len),
89 }
90 }
91
92 pub fn bytes(&self) -> &'a [u8] {
94 self.data
95 }
96
97 pub fn to_str(&self) -> Result<&'a str, std::str::Utf8Error> {
99 std::str::from_utf8(self.data)
100 }
101
102 pub fn to_str_lossy(&self) -> std::borrow::Cow<'a, str> {
104 String::from_utf8_lossy(self.data)
105 }
106}
107
108impl fmt::Debug for Str<'_> {
109 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
110 write!(f, "{}", self.to_str_lossy())
111 }
112}
113
114impl<'a> std::ops::Deref for Str<'a> {
115 type Target = &'a [u8];
116
117 fn deref(&self) -> &Self::Target {
118 &self.data
119 }
120}
121
122impl AsRef<[u8]> for Str<'_> {
123 fn as_ref(&self) -> &[u8] {
124 self.data
125 }
126}
127
128#[derive(Debug)]
153pub struct StrBuilder {
154 pub ptr: *const std::os::raw::c_char,
156 pub len: usize,
158}
159
160impl StrBuilder {
161 pub fn new() -> Self {
163 StrBuilder {
164 ptr: std::ptr::null(),
165 len: 0,
166 }
167 }
168
169 pub unsafe fn build<'a, 'b>(&'a self) -> Str<'b> {
180 Str::from_raw_parts(self.ptr, self.len)
181 }
182}
183
184impl Default for StrBuilder {
185 fn default() -> Self {
186 Self::new()
187 }
188}
189
190#[macro_export]
224macro_rules! ffi_box {
225 (@impl, $type:ident, $boxed_type:ident, new($func:path)) => {
226 impl $type {
227 #[allow(clippy::new_ret_no_self)]
228 pub fn new() -> $boxed_type {
229 unsafe { $boxed_type { ptr: std::ptr::NonNull::new($func()).unwrap() } }
230 }
231 }
232
233 impl Default for $boxed_type {
234 fn default() -> $boxed_type {
235 $type::new()
236 }
237 }
238 };
239
240 (@impl, $type:ident, $boxed_type:ident, clone($func:path)) => {
241 impl Clone for $boxed_type {
242 fn clone(&self) -> $boxed_type {
243 self.as_ref( ).to_owned( )
244 }
245 }
246
247 impl std::borrow::ToOwned for $type {
248 type Owned = $boxed_type;
249
250 fn to_owned(&self) -> Self::Owned {
251 unsafe{ $boxed_type::from_raw($func(self)) }
252 }
253 }
254 };
255
256 ($type:ident, $boxed_type:ident, debug, delete($delete_func:path) $(, $func_type:ident($func:path))*) => {
257 ffi_box!($type, $boxed_type, delete($delete_func) $(, $func_type($func))*);
258
259 impl std::fmt::Debug for $boxed_type {
260 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
261 self.ptr.fmt(f)
262 }
263 }
264 };
265
266 ($type:ident, $boxed_type:ident, delete($delete_func:path) $(, $func_type:ident($func:path))*) => {
267 pub struct $boxed_type {
268 ptr: std::ptr::NonNull<$type>,
269 }
270
271 impl $boxed_type {
272 pub unsafe fn from_raw( ptr: *mut $type ) -> Self {
279 Self{ ptr: std::ptr::NonNull::new(ptr).unwrap() }
280 }
281
282 pub unsafe fn from_raw_checked( ptr: *mut $type ) -> Option<Self> {
289 std::ptr::NonNull::new(ptr).map(|ptr| Self{ptr})
290 }
291
292 pub fn leak(self) -> *mut $type {
294 let ptr = self.ptr.as_ptr();
295 std::mem::forget( self );
296 ptr
297 }
298 }
299
300 impl std::borrow::Borrow<$type> for $boxed_type {
301 fn borrow(&self) -> &$type {
302 self.as_ref()
303 }
304 }
305
306 impl Drop for $boxed_type {
307 fn drop(&mut self) {
308 unsafe {
309 $delete_func( self.ptr.as_ptr() );
310 }
311 }
312 }
313
314 impl std::ops::Deref for $boxed_type {
315 type Target = $type;
316
317 fn deref(&self) -> &Self::Target {
318 unsafe{self.ptr.as_ref()}
319 }
320 }
321
322 impl std::ops::DerefMut for $boxed_type {
323 fn deref_mut(&mut self) -> &mut Self::Target {
324 unsafe{self.ptr.as_mut()}
325 }
326 }
327
328 impl AsRef<$type> for $boxed_type {
329 fn as_ref(&self) -> &$type {
330 unsafe{self.ptr.as_ref()}
331 }
332 }
333
334 impl AsMut<$type> for $boxed_type {
335 fn as_mut(&mut self) -> &mut $type {
336 unsafe{self.ptr.as_mut()}
337 }
338 }
339
340 $(ffi_box!(@impl, $type, $boxed_type, $func_type($func));)*
341 };
342}
343
344#[macro_export]
380macro_rules! ffi_iter {
381 (@impl, struct, $iterator_type:ident($container:ident),) => {
382 #[derive(Clone)]
383 pub struct $iterator_type<'a> {
384 container: &'a $container,
385 pos: usize,
386 len: usize,
387 }
388 };
389 (@impl, struct, $iterator_type:ident($container:ident), mut) => {
390 pub struct $iterator_type<'a> {
391 container: &'a mut $container,
392 pos: usize,
393 len: usize,
394 }
395 };
396
397 (@impl, lifetime, $iterator_type:ident,) => {
398 $iterator_type<'a>
399 };
400 (@impl, lifetime, $iterator_type:ident, mut) => {
401 $iterator_type<'_>
402 };
403
404 ($iterator_type:ident($container:ident) -> $(($mutability:ident))? $type:ident, len($len_func:path), get($get_func:path)) => {
405 ffi_iter!(@impl, struct, $iterator_type($container), $($mutability)*);
406
407 impl<'a> $iterator_type<'a> {
408 pub unsafe fn new(container: &'a $($mutability)* $container) -> Self {
415 Self {
416 len: $len_func(container),
417 container,
418 pos: 0,
419 }
420 }
421
422 pub fn index(&$($mutability)* self, index: usize) -> &'a $type {
423 assert!(index + self.pos < self.len);
424 unsafe { &$($mutability)* *$get_func(self.container, index + self.pos) }
425 }
426
427 pub fn slice<R: std::ops::RangeBounds<usize>>(& $($mutability)* self, range: R) -> ffi_iter!(@impl, lifetime, $iterator_type, $($mutability)*) {
433 use std::ops::Bound;
434 let pos = match range.start_bound() {
435 Bound::Included(&idx) => self.pos + idx,
436 Bound::Excluded(&idx) => self.pos + idx + 1,
437 Bound::Unbounded => self.pos,
438 };
439 let len = match range.end_bound() {
440 Bound::Included(&idx) => self.pos + idx + 1,
441 Bound::Excluded(&idx) => self.pos + idx,
442 Bound::Unbounded => self.len,
443 };
444 $iterator_type {
445 container: self.container,
446 pos,
447 len,
448 }
449 }
450 }
451
452 impl<'a> Iterator for $iterator_type<'a> {
453 type Item = &'a $($mutability)* $type;
454 fn next(&mut self) -> Option<Self::Item> {
455 if self.pos < self.len {
456 let result = unsafe { &$($mutability)* *$get_func(self.container, self.pos) };
457 self.pos += 1;
458 Some(result)
459 } else {
460 None
461 }
462 }
463
464 fn size_hint(&self) -> (usize, Option<usize>) {
465 (self.len - self.pos, Some(self.len - self.pos))
466 }
467 }
468
469 impl<'a> DoubleEndedIterator for $iterator_type<'a> {
470 fn next_back(&mut self) -> Option<Self::Item> {
471 if self.pos < self.len {
472 let result = unsafe { &$($mutability)* *$get_func(self.container, self.len - 1) };
473 self.len -= 1;
474 Some(result)
475 } else {
476 None
477 }
478 }
479 }
480
481 impl<'a> std::iter::FusedIterator for $iterator_type<'a> {}
482
483 impl<'a> ExactSizeIterator for $iterator_type<'a> {}
484 };
485}
486
487#[macro_export]
518macro_rules! ffi_vec {
519 ($vec_type:ident($iter_type:ident, $iter_mut_type:ident) -> $type:ident,
520 len($len_func:path),
521 get($get_func:path),
522 get_mut($get_mut_func:path),
523 grow($grow_func:path),
524 clear($clear_func:path)) => {
525 $crate::ffi_iter!(
526 $iter_type($vec_type) -> $type,
527 len($len_func),
528 get($get_func)
529 );
530 $crate::ffi_iter!(
531 $iter_mut_type($vec_type) -> (mut) $type,
532 len($len_func),
533 get($get_mut_func)
534 );
535 impl $vec_type {
536 pub fn iter(&self) -> $iter_type {
538 unsafe {$iter_type::new(self)}
539 }
540
541 pub fn iter_mut(&mut self) -> $iter_mut_type {
543 unsafe {$iter_mut_type::new(self)}
544 }
545
546 pub fn grow(&mut self) -> &mut $type {
547 unsafe {&mut *$grow_func(self)}
548 }
549
550 pub fn clear(&mut self) {
551 unsafe {$clear_func(self)};
552 }
553
554 pub fn len(&self) -> usize{
555 unsafe {$len_func(self)}
556 }
557
558 pub fn get(&self, index: usize) -> Option<&$type> {
559 if index >= self.len() {
560 None
561 } else {
562 unsafe {Some(&*$get_func(self, index))}
563 }
564 }
565
566 pub fn first(&self) -> Option<&$type> {
567 self.get(0)
568 }
569
570 pub fn first_mut(&mut self) -> Option<&mut $type> {
571 self.get_mut(0)
572 }
573
574 pub fn last(&self) -> Option<&$type> {
575 self.get(self.len().wrapping_sub(1))
576 }
577
578 pub fn last_mut(&mut self) -> Option<&mut $type> {
579 self.get_mut(self.len().wrapping_sub(1))
580 }
581
582 pub fn get_mut(&mut self, index: usize) -> Option<&mut $type> {
583 if index >= self.len() {
584 None
585 } else {
586 unsafe {Some(&mut *$get_mut_func(self, index))}
587 }
588 }
589 }
590
591 impl std::ops::Index<usize> for $vec_type {
592 type Output = $type;
593
594 fn index(&self, index: usize) -> &$type {
595 self.get(index).expect("Out of bounds")
596 }
597 }
598
599 impl std::ops::IndexMut<usize> for $vec_type {
600 fn index_mut(&mut self, index: usize) -> &mut $type {
601 self.get_mut(index).expect("Out of bounds")
602 }
603 }
604 };
605}
606
607#[cfg(test)]
608mod tests {
609 #![allow(dead_code)]
610 use super::*;
611
612 #[derive(Debug)]
613 pub struct A {}
614
615 unsafe fn create_a() -> *mut A {
616 Box::leak(Box::new(A {}))
617 }
618
619 unsafe fn delete_a(ptr: *mut A) {
620 std::mem::drop(Box::from_raw(ptr));
621 }
622
623 ffi_box!(A, BoxedA, debug, delete(delete_a), new(create_a));
624
625 #[test]
626 fn boxed_new() {
627 {
628 let _a = A::new();
629 }
630 }
631
632 #[test]
633 fn debug_a() {
634 format!("{:?}", A::new());
635 }
636
637 pub struct B {}
638
639 unsafe fn create_b() -> *mut B {
640 Box::leak(Box::new(B {}))
641 }
642
643 unsafe fn delete_b(ptr: *mut B) {
644 std::mem::drop(Box::from_raw(ptr));
645 }
646
647 ffi_box!(B, BoxedB, delete(delete_b));
648
649 #[test]
650 fn boxed_from_raw() {
651 {
652 let b = unsafe { BoxedB::from_raw(create_b()) };
653 unsafe {
654 delete_b(b.leak());
655 }
656 }
657 }
658
659 pub struct C {}
660
661 unsafe fn create_c() -> *mut C {
662 Box::leak(Box::new(C {}))
663 }
664
665 unsafe fn delete_c(ptr: *mut C) {
666 std::mem::drop(Box::from_raw(ptr));
667 }
668
669 unsafe fn clone_c(_ptr: *const C) -> *mut C {
670 Box::leak(Box::new(C {}))
671 }
672
673 ffi_box!(C, BoxedC, delete(delete_c), new(create_c), clone(clone_c));
674
675 #[test]
676 fn boxed_clone() {
677 {
678 let c = C::new();
679 let _d = c.clone();
680 let _e = (&c as &C).to_owned();
681 }
682 }
683
684 pub struct MyVec(Vec<usize>);
685
686 unsafe fn vec_len(ptr: *const MyVec) -> usize {
687 (*ptr).0.len()
688 }
689
690 unsafe fn vec_get(ptr: *const MyVec, index: usize) -> *const usize {
691 &(*ptr).0[index]
692 }
693
694 ffi_iter!(MyVecIter(MyVec) -> usize, len(vec_len), get(vec_get));
695
696 #[test]
697 fn iter() {
698 let data = MyVec(vec![0, 1, 2, 3, 4, 5, 6, 7]);
699 let data_rev = MyVec(data.0.iter().cloned().rev().collect());
700 let mut iter = unsafe { MyVecIter::new(&data) };
701 let collected: Vec<_> = iter.clone().cloned().collect();
702 assert_eq!(collected, data.0);
703 let collected_rev: Vec<_> = iter.clone().rev().cloned().collect();
704 assert_eq!(collected_rev, data_rev.0);
705
706 assert_eq!(data.0.len(), iter.len());
707 for x in 0..=7 {
708 assert_eq!(x, *iter.index(x));
709 }
710 iter.next();
711 assert_eq!(data.0.len() - 1, iter.len());
712 for x in 0..=6 {
713 assert_eq!(x + 1, *iter.index(x));
714 }
715
716 let x;
717 {
718 let iter_scoped = unsafe { MyVecIter::new(&data) };
719 x = iter_scoped.index(2);
720 }
721 assert_eq!(x, &data.0[2]);
722 }
723
724 #[test]
725 fn iter_slice() {
726 let data = MyVec(vec![0, 1, 2, 3, 4, 5, 6, 7]);
727 let iter = unsafe { MyVecIter::new(&data) };
728
729 let mut sliced_once = iter.slice(1..7);
730 let mut sliced_twice = sliced_once.slice(1..5);
731 assert_eq!(sliced_once.index(0), &1);
732 assert_eq!(sliced_once.index(5), &6);
733 assert_eq!(sliced_once.next(), Some(&1));
734 assert_eq!(sliced_once.next(), Some(&2));
735 assert_eq!(sliced_once.next(), Some(&3));
736 assert_eq!(sliced_once.next(), Some(&4));
737 assert_eq!(sliced_once.next(), Some(&5));
738 assert_eq!(sliced_once.next(), Some(&6));
739 assert_eq!(sliced_once.next(), None);
740
741 assert_eq!(sliced_twice.index(0), &2);
742 assert_eq!(sliced_twice.index(3), &5);
743 assert_eq!(sliced_twice.next(), Some(&2));
744 assert_eq!(sliced_twice.next(), Some(&3));
745 assert_eq!(sliced_twice.next(), Some(&4));
746 assert_eq!(sliced_twice.next(), Some(&5));
747 assert_eq!(sliced_twice.next(), None);
748
749 let sliced_unbounded = iter.slice(..);
750 assert_eq!(sliced_unbounded.index(0), &0);
751 assert_eq!(sliced_unbounded.index(7), &7);
752 assert_eq!(sliced_unbounded.copied().collect::<Vec<_>>(), data.0);
753
754 let sliced_inclusive = iter.slice(0..=7);
755 assert_eq!(sliced_inclusive.index(0), &0);
756 assert_eq!(sliced_inclusive.index(7), &7);
757 assert_eq!(sliced_inclusive.copied().collect::<Vec<_>>(), data.0);
758 }
759
760 #[test]
761 fn empty_str() {
762 let empty1 = unsafe { Str::from_raw_parts(std::ptr::null(), 10) };
763 assert_eq!(empty1.bytes(), b"");
764 let empty2 = Some(unsafe { Str::from_raw_parts(std::ptr::null(), 10) });
765 assert!(empty2.is_some()); }
767
768 #[test]
769 fn str_utf8() {
770 let str_ascii =
771 unsafe { Str::from_raw_parts(b"abcde" as *const _ as *const std::os::raw::c_char, 5) };
772 assert_eq!(str_ascii.to_str(), Ok("abcde"));
773 let str_utf8 = unsafe {
774 Str::from_raw_parts(
775 b"abc\xce\xb1de" as *const _ as *const std::os::raw::c_char,
776 7,
777 )
778 };
779 assert_eq!(str_utf8.to_str(), Ok("abcαde"));
780 assert_eq!(
781 str_utf8.to_str_lossy(),
782 std::borrow::Cow::Borrowed("abcαde")
783 );
784 let str_invalid_utf8 = unsafe {
785 Str::from_raw_parts(
786 b"abc\x00\xb1de" as *const _ as *const std::os::raw::c_char,
787 7,
788 )
789 };
790 assert!(str_invalid_utf8.to_str().is_err());
791 match str_invalid_utf8.to_str_lossy() {
792 std::borrow::Cow::Owned(x) => {
793 assert_eq!(x, String::from("abc\0�de"));
794 }
795 _ => panic!("UTF decoding should have failed"),
796 }
797 }
798
799 #[test]
800 fn str_builder() {
801 struct A {}
802
803 impl A {
804 fn to_str_with_bound_lifetime(&self) -> &str {
805 let mut result = StrBuilder::new();
806 result.ptr = b"bla".as_ptr() as *const _;
807 result.len = 3;
808
809 unsafe { result.build().to_str().unwrap() }
810 }
811 }
812 }
813
814 unsafe fn vec_get_mut(c: *mut MyVec, pos: usize) -> *mut usize {
815 &mut (*c).0[pos]
816 }
817 unsafe fn vec_grow(c: *mut tests::MyVec) -> *mut usize {
818 (*c).0.push(Default::default());
819 &mut *(*c).0.last_mut().unwrap()
820 }
821 unsafe fn vec_clear(c: *mut MyVec) {
822 (*c).0.clear();
823 }
824
825 ffi_vec!(
826 MyVec(MyVecIterConst, MyVecIterMut) -> usize,
827 len(vec_len),
828 get(vec_get),
829 get_mut(vec_get_mut),
830 grow(vec_grow),
831 clear(vec_clear)
832 );
833
834 #[test]
835 fn vec() {
836 let mut data = MyVec(vec![0, 1, 2, 3, 4, 5, 6, 7]);
837 assert_eq!(data.len(), 8);
838 data[0] = 10;
839 assert_eq!(data[0], 10);
840 assert_eq!(data.first(), Some(&10));
841 *data.last_mut().unwrap() = 99;
842 assert_eq!(data[7], 99);
843 assert_eq!(data.last(), Some(&99));
844 data.clear();
845 assert_eq!(data.len(), 0);
846 *data.grow() = 100;
847 assert_eq!(data.len(), 1);
848 assert_eq!(data[0], 100);
849 }
850}