Skip to content

Commit 5ec4e03

Browse files
committed
Add From<Vec> and Into<Vec> support to MultiValue and Variadic types
1 parent d27d136 commit 5ec4e03

File tree

2 files changed

+88
-19
lines changed

2 files changed

+88
-19
lines changed

src/multi.rs

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,23 @@ impl MultiValue {
124124
MultiValue(VecDeque::with_capacity(capacity))
125125
}
126126

127+
/// Creates a `MultiValue` container from vector of values.
128+
///
129+
/// This methods needs *O*(*n*) data movement if the circular buffer doesn't happen to be at the
130+
/// beginning of the allocation.
131+
#[inline]
132+
pub fn from_vec(vec: Vec<Value>) -> MultiValue {
133+
vec.into()
134+
}
135+
136+
/// Consumes the `MultiValue` and returns a vector of values.
137+
///
138+
/// This methods works in *O*(1) time and does not allocate any additional memory.
139+
#[inline]
140+
pub fn into_vec(self) -> Vec<Value> {
141+
self.into()
142+
}
143+
127144
#[inline]
128145
pub(crate) fn from_lua_iter<T: IntoLua>(lua: &Lua, iter: impl IntoIterator<Item = T>) -> Result<Self> {
129146
let iter = iter.into_iter();
@@ -135,6 +152,20 @@ impl MultiValue {
135152
}
136153
}
137154

155+
impl From<Vec<Value>> for MultiValue {
156+
#[inline]
157+
fn from(value: Vec<Value>) -> Self {
158+
MultiValue(value.into())
159+
}
160+
}
161+
162+
impl From<MultiValue> for Vec<Value> {
163+
#[inline]
164+
fn from(value: MultiValue) -> Self {
165+
value.0.into()
166+
}
167+
}
168+
138169
impl FromIterator<Value> for MultiValue {
139170
#[inline]
140171
fn from_iter<I: IntoIterator<Item = Value>>(iter: I) -> Self {
@@ -203,19 +234,46 @@ impl FromLuaMulti for MultiValue {
203234
/// # Ok(())
204235
/// # }
205236
/// ```
206-
#[derive(Debug, Clone)]
237+
#[derive(Default, Debug, Clone)]
207238
pub struct Variadic<T>(Vec<T>);
208239

209240
impl<T> Variadic<T> {
210241
/// Creates an empty `Variadic` wrapper containing no values.
211242
pub const fn new() -> Variadic<T> {
212243
Variadic(Vec::new())
213244
}
245+
246+
/// Creates an empty `Variadic` container with space for at least `capacity` elements.
247+
pub fn with_capacity(capacity: usize) -> Variadic<T> {
248+
Variadic(Vec::with_capacity(capacity))
249+
}
250+
}
251+
252+
impl<T> Deref for Variadic<T> {
253+
type Target = Vec<T>;
254+
255+
fn deref(&self) -> &Self::Target {
256+
&self.0
257+
}
214258
}
215259

216-
impl<T> Default for Variadic<T> {
217-
fn default() -> Variadic<T> {
218-
const { Variadic::new() }
260+
impl<T> DerefMut for Variadic<T> {
261+
fn deref_mut(&mut self) -> &mut Self::Target {
262+
&mut self.0
263+
}
264+
}
265+
266+
impl<T> From<Vec<T>> for Variadic<T> {
267+
#[inline]
268+
fn from(vec: Vec<T>) -> Self {
269+
Variadic(vec)
270+
}
271+
}
272+
273+
impl<T> From<Variadic<T>> for Vec<T> {
274+
#[inline]
275+
fn from(value: Variadic<T>) -> Self {
276+
value.0
219277
}
220278
}
221279

@@ -234,20 +292,6 @@ impl<T> IntoIterator for Variadic<T> {
234292
}
235293
}
236294

237-
impl<T> Deref for Variadic<T> {
238-
type Target = Vec<T>;
239-
240-
fn deref(&self) -> &Self::Target {
241-
&self.0
242-
}
243-
}
244-
245-
impl<T> DerefMut for Variadic<T> {
246-
fn deref_mut(&mut self) -> &mut Self::Target {
247-
&mut self.0
248-
}
249-
}
250-
251295
impl<T: IntoLua> IntoLuaMulti for Variadic<T> {
252296
#[inline]
253297
fn into_lua_multi(self, lua: &Lua) -> Result<MultiValue> {

tests/multi.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use mlua::{Error, ExternalError, IntoLuaMulti, Lua, Result, String, Value};
1+
use mlua::{Error, ExternalError, IntoLuaMulti, Lua, MultiValue, Result, String, Value, Variadic};
22

33
#[test]
44
fn test_result_conversions() -> Result<()> {
@@ -58,3 +58,28 @@ fn test_result_conversions() -> Result<()> {
5858

5959
Ok(())
6060
}
61+
62+
#[test]
63+
fn test_multivalue() {
64+
let mut multi = MultiValue::with_capacity(3);
65+
multi.push_back(Value::Integer(1));
66+
multi.push_back(Value::Integer(2));
67+
multi.push_front(Value::Integer(3));
68+
assert_eq!(multi.iter().filter_map(|v| v.as_integer()).sum::<i64>(), 6);
69+
70+
let vec = multi.into_vec();
71+
assert_eq!(&vec, &[Value::Integer(3), Value::Integer(1), Value::Integer(2)]);
72+
let _multi2 = MultiValue::from_vec(vec);
73+
}
74+
75+
#[test]
76+
fn test_variadic() {
77+
let mut var = Variadic::with_capacity(3);
78+
var.extend_from_slice(&[1, 2, 3]);
79+
assert_eq!(var.iter().sum::<u32>(), 6);
80+
81+
let vec = Vec::<u32>::from(var);
82+
assert_eq!(&vec, &[1, 2, 3]);
83+
let var2 = Variadic::from(vec);
84+
assert_eq!(var2.as_slice(), &[1, 2, 3]);
85+
}

0 commit comments

Comments
 (0)