nvim_types/
kvec.rs

1//! This module contains functionality common to both `Array`s and
2//! `Dictionary`s.
3
4use std::ops::{Deref, DerefMut};
5use std::ptr;
6use std::slice;
7
8use crate::NonOwning;
9
10// https://github.com/attractivechaos/klib/blob/master/kvec.h#L55
11//
12/// Binding to Klib's [`kvec`][1].
13///
14/// [1]: https://github.com/attractivechaos/klib/blob/master/kvec.h
15#[repr(C)]
16pub struct KVec<T> {
17    #[cfg(feature = "neovim-0-7")]
18    pub(crate) items: *mut T,
19    pub(crate) size: usize,
20    pub(crate) capacity: usize,
21    #[cfg(not(feature = "neovim-0-7"))]
22    pub(crate) items: *mut T,
23}
24
25impl<T> Default for KVec<T> {
26    #[inline]
27    fn default() -> Self {
28        Self::new()
29    }
30}
31
32impl<T> KVec<T> {
33    /// Creates a new empty `Collection`.
34    #[inline]
35    pub const fn new() -> Self {
36        Self { items: std::ptr::null_mut(), size: 0, capacity: 0 }
37    }
38
39    /// The number of items in the collection.
40    #[inline]
41    pub const fn len(&self) -> usize {
42        self.size
43    }
44
45    #[inline]
46    pub const fn is_empty(&self) -> bool {
47        self.len() == 0
48    }
49
50    #[inline]
51    pub(crate) fn as_slice(&self) -> &[T] {
52        if self.items.is_null() {
53            &[]
54        } else {
55            unsafe { slice::from_raw_parts(self.items, self.size) }
56        }
57    }
58
59    #[inline]
60    pub(crate) fn as_mut_slice(&mut self) -> &mut [T] {
61        unsafe { slice::from_raw_parts_mut(self.items, self.size) }
62    }
63
64    #[inline]
65    pub(crate) unsafe fn from_raw_parts(
66        ptr: *mut T,
67        size: usize,
68        capacity: usize,
69    ) -> Self {
70        Self { items: ptr, size, capacity }
71    }
72
73    /// Make a non-owning version of this `Collection`.
74    #[inline]
75    #[doc(hidden)]
76    pub fn non_owning(&self) -> NonOwning<'_, Self> {
77        NonOwning::new(Self { ..*self })
78    }
79}
80
81impl<T: Clone> Clone for KVec<T> {
82    fn clone(&self) -> Self {
83        self.as_slice().to_owned().into()
84    }
85}
86
87impl<T> Drop for KVec<T> {
88    fn drop(&mut self) {
89        unsafe {
90            ptr::drop_in_place(ptr::slice_from_raw_parts_mut(
91                self.items, self.size,
92            ))
93        }
94    }
95}
96
97impl<T: PartialEq> PartialEq for KVec<T> {
98    #[inline]
99    fn eq(&self, other: &Self) -> bool {
100        self.as_slice() == other.as_slice()
101    }
102}
103
104impl<T> Deref for KVec<T> {
105    type Target = [T];
106
107    fn deref(&self) -> &[T] {
108        self.as_slice()
109    }
110}
111
112impl<T> DerefMut for KVec<T> {
113    fn deref_mut(&mut self) -> &mut [T] {
114        self.as_mut_slice()
115    }
116}
117
118impl<T> From<Vec<T>> for KVec<T> {
119    #[inline]
120    fn from(vec: Vec<T>) -> Self {
121        let size = vec.len();
122        let capacity = vec.capacity();
123        let ptr = vec.leak() as *mut [T] as *mut T;
124
125        unsafe { Self::from_raw_parts(ptr, size, capacity) }
126    }
127}
128
129impl<T> From<KVec<T>> for Vec<T> {
130    #[inline]
131    fn from(coll: KVec<T>) -> Self {
132        unsafe {
133            if coll.items.is_null() {
134                Vec::new()
135            } else {
136                Vec::from_raw_parts(coll.items, coll.size, coll.capacity)
137            }
138        }
139    }
140}