1use std::{fmt, marker::PhantomData, mem, ptr};
4
5use crate::{ffi, translate::*};
6
7const MIN_SIZE: usize = 256;
10
11pub struct Slice<T: TransparentType> {
16 ptr: ptr::NonNull<T::GlibType>,
17 len: usize,
18 capacity: usize,
19}
20
21unsafe impl<T: TransparentType + Send> Send for Slice<T> {}
22
23unsafe impl<T: TransparentType + Sync> Sync for Slice<T> {}
24
25impl<T: fmt::Debug + TransparentType> fmt::Debug for Slice<T> {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 self.as_slice().fmt(f)
28 }
29}
30
31impl<T: PartialEq + TransparentType> PartialEq for Slice<T> {
32 #[inline]
33 fn eq(&self, other: &Self) -> bool {
34 self.as_slice() == other.as_slice()
35 }
36}
37
38impl<T: Eq + TransparentType> Eq for Slice<T> {}
39
40impl<T: PartialOrd + TransparentType> PartialOrd for Slice<T> {
41 #[inline]
42 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
43 self.as_slice().partial_cmp(other.as_slice())
44 }
45}
46
47impl<T: Ord + TransparentType> Ord for Slice<T> {
48 #[inline]
49 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
50 self.as_slice().cmp(other.as_slice())
51 }
52}
53
54impl<T: std::hash::Hash + TransparentType> std::hash::Hash for Slice<T> {
55 #[inline]
56 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
57 self.as_slice().hash(state)
58 }
59}
60
61impl<T: PartialEq + TransparentType> PartialEq<[T]> for Slice<T> {
62 #[inline]
63 fn eq(&self, other: &[T]) -> bool {
64 self.as_slice() == other
65 }
66}
67
68impl<T: PartialEq + TransparentType> PartialEq<Slice<T>> for [T] {
69 #[inline]
70 fn eq(&self, other: &Slice<T>) -> bool {
71 self == other.as_slice()
72 }
73}
74
75impl<T: TransparentType> Drop for Slice<T> {
76 #[inline]
77 fn drop(&mut self) {
78 unsafe {
79 let len = mem::replace(&mut self.len, 0);
80 if mem::needs_drop::<T>() {
81 for i in 0..len {
82 ptr::drop_in_place::<T>(self.ptr.as_ptr().add(i) as *mut T);
83 }
84 }
85
86 let capacity = mem::replace(&mut self.capacity, 0);
87 if capacity != 0 {
88 ffi::g_free(self.ptr.as_ptr() as ffi::gpointer);
89 }
90 }
91 }
92}
93
94impl<T: TransparentType> AsRef<[T]> for Slice<T> {
95 #[inline]
96 fn as_ref(&self) -> &[T] {
97 self.as_slice()
98 }
99}
100
101impl<T: TransparentType> AsMut<[T]> for Slice<T> {
102 #[inline]
103 fn as_mut(&mut self) -> &mut [T] {
104 self.as_mut_slice()
105 }
106}
107
108impl<T: TransparentType> std::borrow::Borrow<[T]> for Slice<T> {
109 #[inline]
110 fn borrow(&self) -> &[T] {
111 self.as_slice()
112 }
113}
114
115impl<T: TransparentType> std::borrow::BorrowMut<[T]> for Slice<T> {
116 #[inline]
117 fn borrow_mut(&mut self) -> &mut [T] {
118 self.as_mut_slice()
119 }
120}
121
122impl<T: TransparentType> std::ops::Deref for Slice<T> {
123 type Target = [T];
124
125 #[inline]
126 fn deref(&self) -> &[T] {
127 self.as_slice()
128 }
129}
130
131impl<T: TransparentType> std::ops::DerefMut for Slice<T> {
132 #[inline]
133 fn deref_mut(&mut self) -> &mut [T] {
134 self.as_mut_slice()
135 }
136}
137
138impl<T: TransparentType> Default for Slice<T> {
139 #[inline]
140 fn default() -> Self {
141 Self::new()
142 }
143}
144
145impl<T: TransparentType> std::iter::Extend<T> for Slice<T> {
146 #[inline]
147 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
148 let iter = iter.into_iter();
149 self.reserve(iter.size_hint().0);
150
151 for item in iter {
152 self.push(item);
153 }
154 }
155}
156
157impl<'a, T: TransparentType + 'a> std::iter::Extend<&'a T> for Slice<T> {
158 #[inline]
159 fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
160 let iter = iter.into_iter();
161 self.reserve(iter.size_hint().0);
162
163 for item in iter {
164 self.push(item.clone());
165 }
166 }
167}
168
169impl<T: TransparentType> std::iter::FromIterator<T> for Slice<T> {
170 #[inline]
171 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
172 let iter = iter.into_iter();
173 let mut s = Self::with_capacity(iter.size_hint().0);
174 for item in iter {
175 s.push(item);
176 }
177 s
178 }
179}
180
181impl<'a, T: TransparentType> std::iter::IntoIterator for &'a Slice<T> {
182 type Item = &'a T;
183 type IntoIter = std::slice::Iter<'a, T>;
184
185 #[inline]
186 fn into_iter(self) -> Self::IntoIter {
187 self.as_slice().iter()
188 }
189}
190
191impl<'a, T: TransparentType> std::iter::IntoIterator for &'a mut Slice<T> {
192 type Item = &'a mut T;
193 type IntoIter = std::slice::IterMut<'a, T>;
194
195 #[inline]
196 fn into_iter(self) -> Self::IntoIter {
197 self.as_mut_slice().iter_mut()
198 }
199}
200
201impl<T: TransparentType> std::iter::IntoIterator for Slice<T> {
202 type Item = T;
203 type IntoIter = IntoIter<T>;
204
205 #[inline]
206 fn into_iter(self) -> Self::IntoIter {
207 IntoIter::new(self)
208 }
209}
210
211pub struct IntoIter<T: TransparentType> {
212 ptr: ptr::NonNull<T::GlibType>,
213 idx: ptr::NonNull<T::GlibType>,
214 len: usize,
215 empty: bool,
216}
217
218impl<T: TransparentType> IntoIter<T> {
219 #[inline]
220 fn new(slice: Slice<T>) -> Self {
221 let slice = mem::ManuallyDrop::new(slice);
222 IntoIter {
223 ptr: slice.ptr,
224 idx: slice.ptr,
225 len: slice.len,
226 empty: slice.capacity == 0,
227 }
228 }
229
230 #[inline]
233 pub fn as_slice(&self) -> &[T] {
234 unsafe {
235 if self.len == 0 {
236 &[]
237 } else {
238 std::slice::from_raw_parts(self.idx.as_ptr() as *mut T, self.len)
239 }
240 }
241 }
242
243 #[inline]
246 pub fn as_mut_slice(&mut self) -> &mut [T] {
247 unsafe {
248 if self.len == 0 {
249 &mut []
250 } else {
251 std::slice::from_raw_parts_mut(self.idx.as_ptr() as *mut T, self.len)
252 }
253 }
254 }
255}
256
257impl<T: TransparentType> Drop for IntoIter<T> {
258 #[inline]
259 fn drop(&mut self) {
260 unsafe {
261 let len = mem::replace(&mut self.len, 0);
262 if mem::needs_drop::<T>() {
263 for i in 0..len {
264 ptr::drop_in_place::<T>(self.idx.as_ptr().add(i) as *mut T);
265 }
266 }
267
268 let empty = mem::replace(&mut self.empty, true);
269 if !empty {
270 ffi::g_free(self.ptr.as_ptr() as ffi::gpointer);
271 }
272 }
273 }
274}
275
276impl<T: TransparentType> Iterator for IntoIter<T> {
277 type Item = T;
278
279 #[inline]
280 fn next(&mut self) -> Option<Self::Item> {
281 if self.len == 0 {
282 return None;
283 }
284
285 unsafe {
286 let p = self.idx.as_ptr();
287 self.len -= 1;
288 self.idx = ptr::NonNull::new_unchecked(p.add(1));
289 Some(ptr::read(p as *mut T))
290 }
291 }
292
293 #[inline]
294 fn size_hint(&self) -> (usize, Option<usize>) {
295 (self.len, Some(self.len))
296 }
297
298 #[inline]
299 fn count(self) -> usize {
300 self.len
301 }
302
303 #[inline]
304 fn last(mut self) -> Option<T> {
305 if self.len == 0 {
306 None
307 } else {
308 self.len -= 1;
309 Some(unsafe { ptr::read(self.idx.as_ptr().add(self.len) as *mut T) })
310 }
311 }
312}
313
314impl<T: TransparentType> DoubleEndedIterator for IntoIter<T> {
315 #[inline]
316 fn next_back(&mut self) -> Option<T> {
317 if self.len == 0 {
318 None
319 } else {
320 self.len -= 1;
321 Some(unsafe { ptr::read(self.idx.as_ptr().add(self.len) as *mut T) })
322 }
323 }
324}
325
326impl<T: TransparentType> ExactSizeIterator for IntoIter<T> {}
327
328impl<T: TransparentType> std::iter::FusedIterator for IntoIter<T> {}
329
330impl<T: TransparentType> From<Slice<T>> for Vec<T> {
331 #[inline]
332 fn from(mut value: Slice<T>) -> Self {
333 unsafe {
334 let mut s = Vec::with_capacity(value.len);
335 ptr::copy_nonoverlapping(value.ptr.as_ptr() as *const T, s.as_mut_ptr(), value.len);
336 s.set_len(value.len);
337 value.len = 0;
338 s
339 }
340 }
341}
342
343impl<T: TransparentType> From<Vec<T>> for Slice<T> {
344 #[inline]
345 fn from(mut value: Vec<T>) -> Self {
346 unsafe {
347 let mut s = Self::with_capacity(value.len());
348 ptr::copy_nonoverlapping(value.as_ptr(), s.ptr.as_ptr() as *mut T, value.len());
349 s.len = value.len();
350 value.set_len(0);
351 s
352 }
353 }
354}
355
356impl<T: TransparentType, const N: usize> From<[T; N]> for Slice<T> {
357 #[inline]
358 fn from(value: [T; N]) -> Self {
359 unsafe {
360 let value = mem::ManuallyDrop::new(value);
361 let len = value.len();
362 let mut s = Self::with_capacity(len);
363 ptr::copy_nonoverlapping(value.as_ptr(), s.ptr.as_ptr() as *mut T, len);
364 s.len = len;
365 s
366 }
367 }
368}
369
370impl<'a, T: TransparentType> From<&'a [T]> for Slice<T> {
371 #[inline]
372 fn from(value: &'a [T]) -> Self {
373 unsafe {
374 let mut s = Self::with_capacity(value.len());
375 for (i, item) in value.iter().enumerate() {
376 ptr::write(s.ptr.as_ptr().add(i) as *mut T, item.clone());
377 }
378 s.len = value.len();
379 s
380 }
381 }
382}
383
384impl<'a, T: TransparentType> From<&'a [&'a T]> for Slice<T> {
385 #[inline]
386 fn from(value: &'a [&'a T]) -> Self {
387 unsafe {
388 let mut s = Self::with_capacity(value.len());
389 for (i, item) in value.iter().enumerate() {
390 ptr::write(s.ptr.as_ptr().add(i) as *mut T, (*item).clone());
391 }
392 s.len = value.len();
393 s
394 }
395 }
396}
397
398impl<T: TransparentType> Clone for Slice<T> {
399 #[inline]
400 fn clone(&self) -> Self {
401 Self::from(self.as_slice())
402 }
403}
404
405impl<T: TransparentType> Slice<T> {
406 #[inline]
409 pub unsafe fn from_glib_borrow_num<'a>(ptr: *const T::GlibType, len: usize) -> &'a [T] {
410 unsafe {
411 debug_assert_eq!(mem::size_of::<T>(), mem::size_of::<T::GlibType>());
412 debug_assert!(!ptr.is_null() || len == 0);
413
414 if len == 0 {
415 &[]
416 } else {
417 std::slice::from_raw_parts(ptr as *const T, len)
418 }
419 }
420 }
421
422 #[inline]
425 pub unsafe fn from_glib_borrow_num_mut<'a>(ptr: *mut T::GlibType, len: usize) -> &'a mut [T] {
426 unsafe {
427 debug_assert_eq!(mem::size_of::<T>(), mem::size_of::<T::GlibType>());
428 debug_assert!(!ptr.is_null() || len == 0);
429
430 if len == 0 {
431 &mut []
432 } else {
433 std::slice::from_raw_parts_mut(ptr as *mut T, len)
434 }
435 }
436 }
437
438 #[inline]
441 pub unsafe fn from_glib_ptr_borrow_num<'a>(
442 ptr: *const *const T::GlibType,
443 len: usize,
444 ) -> &'a [&'a T] {
445 unsafe {
446 debug_assert_eq!(mem::size_of::<T>(), mem::size_of::<T::GlibType>());
447 debug_assert!(!ptr.is_null() || len == 0);
448
449 if len == 0 {
450 &[]
451 } else {
452 std::slice::from_raw_parts(ptr as *const &T, len)
453 }
454 }
455 }
456
457 #[inline]
460 pub unsafe fn from_glib_ptr_borrow_num_mut<'a>(
461 ptr: *mut *mut T::GlibType,
462 len: usize,
463 ) -> &'a mut [&'a mut T] {
464 unsafe {
465 debug_assert_eq!(mem::size_of::<T>(), mem::size_of::<T::GlibType>());
466 debug_assert!(!ptr.is_null() || len == 0);
467
468 if len == 0 {
469 &mut []
470 } else {
471 std::slice::from_raw_parts_mut(ptr as *mut &mut T, len)
472 }
473 }
474 }
475
476 #[inline]
479 pub unsafe fn from_glib_none_num(ptr: *const T::GlibType, len: usize) -> Self {
480 unsafe {
481 debug_assert_eq!(mem::size_of::<T>(), mem::size_of::<T::GlibType>());
482 debug_assert!(!ptr.is_null() || len == 0);
483
484 if len == 0 {
485 Slice::default()
486 } else {
487 let s = Self::from_glib_borrow_num(ptr, len);
489 Self::from(s)
490 }
491 }
492 }
493
494 #[inline]
497 pub unsafe fn from_glib_container_num(ptr: *mut T::GlibType, len: usize) -> Self {
498 unsafe {
499 debug_assert_eq!(mem::size_of::<T>(), mem::size_of::<T::GlibType>());
500 debug_assert!(!ptr.is_null() || len == 0);
501
502 if len == 0 {
503 ffi::g_free(ptr as ffi::gpointer);
504 Slice::default()
505 } else {
506 if mem::needs_drop::<T>() {
509 for i in 0..len {
510 let p = ptr.add(i) as *mut T;
511 let clone: T = (*p).clone();
512 ptr::write(p, clone);
513 }
514 }
515
516 Self::from_glib_full_num(ptr, len)
518 }
519 }
520 }
521
522 #[inline]
525 pub unsafe fn from_glib_full_num(ptr: *mut T::GlibType, len: usize) -> Self {
526 unsafe {
527 debug_assert_eq!(mem::size_of::<T>(), mem::size_of::<T::GlibType>());
528 debug_assert!(!ptr.is_null() || len == 0);
529
530 if len == 0 {
531 ffi::g_free(ptr as ffi::gpointer);
532 Slice::default()
533 } else {
534 Slice {
535 ptr: ptr::NonNull::new_unchecked(ptr),
536 len,
537 capacity: len,
538 }
539 }
540 }
541 }
542
543 #[inline]
546 pub fn new() -> Self {
547 debug_assert_eq!(mem::size_of::<T>(), mem::size_of::<T::GlibType>());
548
549 Slice {
550 ptr: ptr::NonNull::dangling(),
551 len: 0,
552 capacity: 0,
553 }
554 }
555
556 #[inline]
559 pub fn with_capacity(capacity: usize) -> Self {
560 let mut s = Self::new();
561 s.reserve(capacity);
562 s
563 }
564
565 #[inline]
568 pub fn as_ptr(&self) -> *const T::GlibType {
569 if self.len == 0 {
570 ptr::null()
571 } else {
572 self.ptr.as_ptr()
573 }
574 }
575
576 #[inline]
579 pub fn as_mut_ptr(&mut self) -> *mut T::GlibType {
580 if self.len == 0 {
581 ptr::null_mut()
582 } else {
583 self.ptr.as_ptr()
584 }
585 }
586
587 #[inline]
590 pub fn into_raw(mut self) -> *mut T::GlibType {
591 if self.len == 0 {
592 ptr::null_mut()
593 } else {
594 self.len = 0;
595 self.capacity = 0;
596 self.ptr.as_ptr()
597 }
598 }
599
600 #[inline]
603 pub fn len(&self) -> usize {
604 self.len
605 }
606
607 #[inline]
610 pub fn is_empty(&self) -> bool {
611 self.len == 0
612 }
613
614 #[inline]
617 pub fn capacity(&self) -> usize {
618 self.capacity
619 }
620
621 pub unsafe fn set_len(&mut self, len: usize) {
628 self.len = len;
629 }
630
631 pub fn reserve(&mut self, additional: usize) {
634 if additional <= self.capacity - self.len {
636 return;
637 }
638
639 let new_capacity = usize::next_power_of_two(std::cmp::max(
640 self.len + additional,
641 MIN_SIZE / mem::size_of::<T>(),
642 ));
643 assert_ne!(new_capacity, 0);
644 assert!(new_capacity > self.capacity);
645
646 unsafe {
647 let ptr = if self.capacity == 0 {
648 ptr::null_mut()
649 } else {
650 self.ptr.as_ptr() as *mut _
651 };
652 let new_ptr =
653 ffi::g_realloc(ptr, mem::size_of::<T>().checked_mul(new_capacity).unwrap())
654 as *mut T::GlibType;
655 self.ptr = ptr::NonNull::new_unchecked(new_ptr);
656 self.capacity = new_capacity;
657 }
658 }
659
660 #[inline]
663 pub fn as_slice(&self) -> &[T] {
664 unsafe {
665 if self.len == 0 {
666 &[]
667 } else {
668 std::slice::from_raw_parts(self.ptr.as_ptr() as *const T, self.len)
669 }
670 }
671 }
672
673 #[inline]
676 pub fn as_mut_slice(&mut self) -> &mut [T] {
677 unsafe {
678 if self.len == 0 {
679 &mut []
680 } else {
681 std::slice::from_raw_parts_mut(self.ptr.as_ptr() as *mut T, self.len)
682 }
683 }
684 }
685
686 #[inline]
689 pub fn clear(&mut self) {
690 unsafe {
691 let len = mem::replace(&mut self.len, 0);
692 if mem::needs_drop::<T>() {
693 for i in 0..len {
694 ptr::drop_in_place::<T>(self.ptr.as_ptr().add(i) as *mut T);
695 }
696 }
697 }
698 }
699
700 #[inline]
703 pub fn extend_from_slice(&mut self, other: &[T]) {
704 if other.len() > self.capacity - self.len {
706 self.reserve(other.len());
707 }
708
709 unsafe {
710 for item in other {
711 ptr::write(self.ptr.as_ptr().add(self.len) as *mut T, item.clone());
712 self.len += 1;
713 }
714 }
715 }
716
717 #[inline]
721 #[allow(clippy::int_plus_one)]
722 pub fn insert(&mut self, index: usize, item: T) {
723 assert!(index <= self.len);
724
725 if 1 > self.capacity - self.len {
727 self.reserve(1);
728 }
729
730 unsafe {
731 if index == self.len {
732 ptr::write(self.ptr.as_ptr().add(self.len) as *mut T, item);
733 } else {
734 let p = self.ptr.as_ptr().add(index);
735 ptr::copy(p, p.add(1), self.len - index);
736 ptr::write(self.ptr.as_ptr().add(index) as *mut T, item);
737 }
738
739 self.len += 1;
740 }
741 }
742
743 #[inline]
746 #[allow(clippy::int_plus_one)]
747 pub fn push(&mut self, item: T) {
748 if 1 > self.capacity - self.len {
750 self.reserve(1);
751 }
752
753 unsafe {
754 ptr::write(self.ptr.as_ptr().add(self.len) as *mut T, item);
755 self.len += 1;
756 }
757 }
758
759 #[inline]
763 pub fn remove(&mut self, index: usize) -> T {
764 assert!(index < self.len);
765
766 unsafe {
767 let p = self.ptr.as_ptr().add(index);
768 let item = ptr::read(p as *mut T);
769 ptr::copy(p.add(1), p, self.len - index - 1);
770
771 self.len -= 1;
772
773 item
774 }
775 }
776
777 #[inline]
780 pub fn pop(&mut self) -> Option<T> {
781 if self.len == 0 {
782 return None;
783 }
784
785 unsafe {
786 self.len -= 1;
787 let p = self.ptr.as_ptr().add(self.len);
788 let item = ptr::read(p as *mut T);
789
790 Some(item)
791 }
792 }
793
794 #[inline]
799 pub fn truncate(&mut self, len: usize) {
800 if self.len <= len {
801 return;
802 }
803
804 unsafe {
805 if mem::needs_drop::<T>() {
806 while self.len > len {
807 self.len -= 1;
808 let p = self.ptr.as_ptr().add(self.len);
809 ptr::drop_in_place::<T>(p as *mut T);
810 }
811 } else {
812 self.len = len;
813 }
814 }
815 }
816}
817
818impl<T: TransparentType + 'static> FromGlibContainer<T::GlibType, *mut T::GlibType> for Slice<T> {
819 unsafe fn from_glib_none_num(ptr: *mut T::GlibType, num: usize) -> Self {
820 unsafe { Self::from_glib_none_num(ptr, num) }
821 }
822
823 #[inline]
824 unsafe fn from_glib_container_num(ptr: *mut T::GlibType, num: usize) -> Self {
825 unsafe { Self::from_glib_container_num(ptr, num) }
826 }
827
828 #[inline]
829 unsafe fn from_glib_full_num(ptr: *mut T::GlibType, num: usize) -> Self {
830 unsafe { Self::from_glib_full_num(ptr, num) }
831 }
832}
833
834impl<T: TransparentType + 'static> FromGlibContainer<T::GlibType, *const T::GlibType> for Slice<T> {
835 unsafe fn from_glib_none_num(ptr: *const T::GlibType, num: usize) -> Self {
836 unsafe { Self::from_glib_none_num(ptr, num) }
837 }
838
839 unsafe fn from_glib_container_num(_ptr: *const T::GlibType, _num: usize) -> Self {
840 unimplemented!();
841 }
842
843 unsafe fn from_glib_full_num(_ptr: *const T::GlibType, _num: usize) -> Self {
844 unimplemented!();
845 }
846}
847
848impl<'a, T: TransparentType + 'a> ToGlibPtr<'a, *mut T::GlibType> for Slice<T> {
849 type Storage = PhantomData<&'a Self>;
850
851 #[inline]
852 fn to_glib_none(&'a self) -> Stash<'a, *mut T::GlibType, Self> {
853 Stash(self.as_ptr() as *mut _, PhantomData)
854 }
855
856 #[inline]
857 fn to_glib_container(&'a self) -> Stash<'a, *mut T::GlibType, Self> {
858 unsafe {
859 let ptr = ffi::g_malloc(mem::size_of::<T>().checked_mul(self.len()).unwrap())
860 as *mut T::GlibType;
861 ptr::copy_nonoverlapping(self.as_ptr(), ptr, self.len());
862 Stash(ptr, PhantomData)
863 }
864 }
865
866 #[inline]
867 fn to_glib_full(&self) -> *mut T::GlibType {
868 self.clone().into_raw()
869 }
870}
871
872impl<'a, T: TransparentType + 'a> ToGlibPtr<'a, *const T::GlibType> for Slice<T> {
873 type Storage = PhantomData<&'a Self>;
874
875 #[inline]
876 fn to_glib_none(&'a self) -> Stash<'a, *const T::GlibType, Self> {
877 Stash(self.as_ptr(), PhantomData)
878 }
879}
880
881impl<'a, T: TransparentType + 'a> ToGlibPtrMut<'a, *mut T::GlibType> for Slice<T> {
882 type Storage = PhantomData<&'a mut Self>;
883
884 #[inline]
885 fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut T::GlibType, Self> {
886 StashMut(self.as_mut_ptr(), PhantomData)
887 }
888}
889
890impl<T: TransparentType + 'static> IntoGlibPtr<*mut T::GlibType> for Slice<T> {
891 #[inline]
892 fn into_glib_ptr(self) -> *mut T::GlibType {
893 self.into_raw()
894 }
895}
896
897impl<T: TransparentPtrType> From<super::PtrSlice<T>> for Slice<T> {
898 fn from(value: super::PtrSlice<T>) -> Self {
899 let len = value.len();
900 let capacity = value.capacity();
901 unsafe {
902 let ptr = value.into_raw();
903 Slice::<T> {
904 ptr: ptr::NonNull::new_unchecked(ptr),
905 len,
906 capacity,
907 }
908 }
909 }
910}
911
912#[cfg(test)]
913mod test {
914 use super::*;
915
916 #[test]
917 fn test_from_glib_full() {
918 let items = [
919 crate::Date::from_dmy(20, crate::DateMonth::November, 2021).unwrap(),
920 crate::Date::from_dmy(21, crate::DateMonth::November, 2021).unwrap(),
921 crate::Date::from_dmy(22, crate::DateMonth::November, 2021).unwrap(),
922 crate::Date::from_dmy(23, crate::DateMonth::November, 2021).unwrap(),
923 ];
924
925 let slice = unsafe {
926 let ptr = ffi::g_malloc(mem::size_of::<ffi::GDate>() * 4) as *mut ffi::GDate;
927 ptr::write(ptr.add(0), *items[0].to_glib_none().0);
928 ptr::write(ptr.add(1), *items[1].to_glib_none().0);
929 ptr::write(ptr.add(2), *items[2].to_glib_none().0);
930 ptr::write(ptr.add(3), *items[3].to_glib_none().0);
931
932 Slice::<crate::Date>::from_glib_full_num(ptr, 4)
933 };
934
935 assert_eq!(&items[..], &*slice);
936 }
937
938 #[test]
939 fn test_from_glib_none() {
940 let items = [
941 crate::Date::from_dmy(20, crate::DateMonth::November, 2021).unwrap(),
942 crate::Date::from_dmy(21, crate::DateMonth::November, 2021).unwrap(),
943 crate::Date::from_dmy(22, crate::DateMonth::November, 2021).unwrap(),
944 crate::Date::from_dmy(23, crate::DateMonth::November, 2021).unwrap(),
945 ];
946
947 let slice = unsafe {
948 Slice::<crate::Date>::from_glib_none_num(items.as_ptr() as *const ffi::GDate, 4)
949 };
950
951 assert_eq!(&items[..], &*slice);
952 }
953
954 #[test]
955 fn test_safe_api() {
956 let items = [
957 crate::Date::from_dmy(20, crate::DateMonth::November, 2021).unwrap(),
958 crate::Date::from_dmy(21, crate::DateMonth::November, 2021).unwrap(),
959 crate::Date::from_dmy(22, crate::DateMonth::November, 2021).unwrap(),
960 ];
961
962 let mut slice = Slice::from(&items[..]);
963 assert_eq!(slice.len(), 3);
964 slice.push(crate::Date::from_dmy(23, crate::DateMonth::November, 2021).unwrap());
965 assert_eq!(slice.len(), 4);
966
967 for (a, b) in Iterator::zip(items.iter(), slice.iter()) {
968 assert_eq!(a, b);
969 }
970 assert_eq!(
971 (slice[3].day(), slice[3].month(), slice[3].year()),
972 (23, crate::DateMonth::November, 2021)
973 );
974
975 let vec = Vec::from(slice);
976 assert_eq!(vec.len(), 4);
977 for (a, b) in Iterator::zip(items.iter(), vec.iter()) {
978 assert_eq!(a, b);
979 }
980 assert_eq!(
981 (vec[3].day(), vec[3].month(), vec[3].year()),
982 (23, crate::DateMonth::November, 2021)
983 );
984
985 let mut slice = Slice::from(vec);
986 assert_eq!(slice.len(), 4);
987 let e = slice.pop().unwrap();
988 assert_eq!(
989 (e.day(), e.month(), e.year()),
990 (23, crate::DateMonth::November, 2021)
991 );
992 assert_eq!(slice.len(), 3);
993 slice.insert(2, e);
994 assert_eq!(slice.len(), 4);
995 assert_eq!(slice[0].day(), 20);
996 assert_eq!(slice[1].day(), 21);
997 assert_eq!(slice[2].day(), 23);
998 assert_eq!(slice[3].day(), 22);
999 let e = slice.remove(2);
1000 assert_eq!(
1001 (e.day(), e.month(), e.year()),
1002 (23, crate::DateMonth::November, 2021)
1003 );
1004 assert_eq!(slice.len(), 3);
1005 slice.push(e);
1006 assert_eq!(slice.len(), 4);
1007
1008 for (a, b) in Iterator::zip(items.iter(), slice) {
1009 assert_eq!(a, &b);
1010 }
1011 }
1012}