1use core::borrow::Borrow;
2use core::fmt;
3use core::ops::{self, Deref, DerefMut};
4use core::slice;
5
6use crate as rune;
7use crate::alloc::alloc::Global;
8use crate::alloc::borrow::TryToOwned;
9use crate::alloc::clone::TryClone;
10use crate::alloc::fmt::TryWrite;
11use crate::alloc::iter::{IteratorExt, TryFromIteratorIn};
12use crate::alloc::{self, Box};
13use crate::Any;
14
15use super::{
16 ConstValue, EmptyConstContext, Formatter, FromConstValue, FromValue, Mut, RawAnyGuard, Ref,
17 RuntimeError, ToConstValue, ToValue, UnsafeToMut, UnsafeToRef, Value, VmErrorKind, VmResult,
18};
19#[cfg(feature = "alloc")]
20use super::{Hasher, ProtocolCaller};
21
22#[repr(transparent)]
24pub struct Tuple {
25 values: [Value],
26}
27
28impl Tuple {
29 pub const fn new(values: &[Value]) -> &Self {
31 unsafe { &*(values as *const _ as *const Self) }
33 }
34
35 pub(crate) fn from_boxed(boxed: Box<[Value]>) -> Box<Self> {
37 let (values, Global) = Box::into_raw_with_allocator(boxed);
38 unsafe { Box::from_raw_in(values as *mut Tuple, Global) }
40 }
41
42 pub fn new_mut(values: &mut [Value]) -> &mut Self {
44 unsafe { &mut *(values as *mut _ as *mut Self) }
46 }
47
48 pub fn get_value<T>(&self, index: usize) -> VmResult<Option<T>>
50 where
51 T: FromValue,
52 {
53 let value = match self.values.get(index) {
54 Some(value) => value.clone(),
55 None => return VmResult::Ok(None),
56 };
57
58 VmResult::Ok(Some(vm_try!(T::from_value(value))))
59 }
60
61 pub(crate) fn hash_with(
62 &self,
63 hasher: &mut Hasher,
64 caller: &mut dyn ProtocolCaller,
65 ) -> VmResult<()> {
66 for value in self.values.iter() {
67 vm_try!(value.hash_with(hasher, caller));
68 }
69
70 VmResult::Ok(())
71 }
72
73 pub(crate) fn debug_fmt_with(
74 &self,
75 f: &mut Formatter,
76 caller: &mut dyn ProtocolCaller,
77 ) -> VmResult<()> {
78 let mut it = self.iter().peekable();
79 vm_try!(vm_write!(f, "("));
80
81 while let Some(value) = it.next() {
82 vm_try!(value.debug_fmt_with(f, caller));
83
84 if it.peek().is_some() {
85 vm_try!(vm_write!(f, ", "));
86 }
87 }
88
89 vm_try!(vm_write!(f, ")"));
90 VmResult::Ok(())
91 }
92
93 pub(crate) fn clone_with(&self, caller: &mut dyn ProtocolCaller) -> VmResult<OwnedTuple> {
94 let mut vec = vm_try!(alloc::Vec::try_with_capacity(self.len()));
95
96 for value in self.values.iter() {
97 let value = vm_try!(value.clone_with(caller));
98 vm_try!(vec.try_push(value));
99 }
100
101 VmResult::Ok(vm_try!(OwnedTuple::try_from(vec)))
102 }
103}
104
105impl ops::Deref for Tuple {
106 type Target = [Value];
107
108 #[inline]
109 fn deref(&self) -> &Self::Target {
110 &self.values
111 }
112}
113
114impl ops::DerefMut for Tuple {
115 #[inline]
116 fn deref_mut(&mut self) -> &mut Self::Target {
117 &mut self.values
118 }
119}
120
121impl<'a> IntoIterator for &'a Tuple {
122 type Item = &'a Value;
123 type IntoIter = slice::Iter<'a, Value>;
124
125 #[inline]
126 fn into_iter(self) -> Self::IntoIter {
127 self.iter()
128 }
129}
130
131impl<'a> IntoIterator for &'a mut Tuple {
132 type Item = &'a mut Value;
133 type IntoIter = slice::IterMut<'a, Value>;
134
135 #[inline]
136 fn into_iter(self) -> Self::IntoIter {
137 self.iter_mut()
138 }
139}
140
141#[derive(Any)]
145#[rune(item = ::std::tuple, name = Tuple)]
146#[repr(transparent)]
147pub struct OwnedTuple {
148 inner: Box<[Value]>,
149}
150
151impl OwnedTuple {
152 pub fn new() -> Self {
162 Self {
163 inner: Box::default(),
164 }
165 }
166
167 pub fn into_boxed_tuple(self) -> Box<Tuple> {
169 Tuple::from_boxed(self.inner)
170 }
171
172 pub fn into_inner(self) -> Box<[Value]> {
174 self.inner
175 }
176}
177
178impl Deref for OwnedTuple {
179 type Target = Tuple;
180
181 #[inline]
182 fn deref(&self) -> &Self::Target {
183 Tuple::new(&self.inner)
184 }
185}
186
187impl DerefMut for OwnedTuple {
188 #[inline]
189 fn deref_mut(&mut self) -> &mut Self::Target {
190 Tuple::new_mut(&mut self.inner)
191 }
192}
193
194impl AsRef<Tuple> for OwnedTuple {
195 #[inline]
196 fn as_ref(&self) -> &Tuple {
197 self
198 }
199}
200
201impl AsMut<Tuple> for OwnedTuple {
202 #[inline]
203 fn as_mut(&mut self) -> &mut Tuple {
204 self
205 }
206}
207
208impl Borrow<Tuple> for OwnedTuple {
209 #[inline]
210 fn borrow(&self) -> &Tuple {
211 self
212 }
213}
214
215impl Default for OwnedTuple {
216 fn default() -> Self {
217 Self::new()
218 }
219}
220
221impl TryClone for OwnedTuple {
222 #[inline]
223 fn try_clone(&self) -> alloc::Result<Self> {
224 Ok(Self {
225 inner: self.inner.try_clone()?,
226 })
227 }
228
229 #[inline]
230 fn try_clone_from(&mut self, source: &Self) -> alloc::Result<()> {
231 self.inner.try_clone_from(&source.inner)
232 }
233}
234
235impl fmt::Debug for OwnedTuple {
236 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
237 write!(f, "(")?;
238
239 let mut it = self.iter();
240 let last = it.next_back();
241
242 for el in it {
243 write!(f, "{:?}, ", el)?;
244 }
245
246 if let Some(last) = last {
247 write!(f, "{:?}", last)?;
248 }
249
250 write!(f, ")")?;
251 Ok(())
252 }
253}
254
255#[cfg(feature = "alloc")]
256impl TryFrom<::rust_alloc::vec::Vec<Value>> for OwnedTuple {
257 type Error = alloc::Error;
258
259 #[inline]
260 fn try_from(vec: ::rust_alloc::vec::Vec<Value>) -> Result<Self, Self::Error> {
261 Ok(Self {
262 inner: alloc::Box::try_from(vec.into_boxed_slice())?,
263 })
264 }
265}
266
267impl TryFrom<alloc::Vec<Value>> for OwnedTuple {
268 type Error = alloc::Error;
269
270 #[inline]
271 fn try_from(vec: alloc::Vec<Value>) -> Result<Self, Self::Error> {
272 Ok(Self {
273 inner: vec.try_into_boxed_slice()?,
274 })
275 }
276}
277
278impl<const N: usize> TryFrom<[Value; N]> for OwnedTuple {
279 type Error = alloc::Error;
280
281 #[inline]
282 fn try_from(values: [Value; N]) -> Result<Self, Self::Error> {
283 Ok(Self {
284 inner: values.try_into()?,
285 })
286 }
287}
288
289impl From<alloc::Box<[Value]>> for OwnedTuple {
290 #[inline]
291 fn from(inner: alloc::Box<[Value]>) -> Self {
292 Self { inner }
293 }
294}
295
296impl TryFrom<alloc::Box<[ConstValue]>> for OwnedTuple {
297 type Error = RuntimeError;
298
299 fn try_from(inner: alloc::Box<[ConstValue]>) -> Result<Self, RuntimeError> {
300 if inner.is_empty() {
301 return Ok(OwnedTuple::new());
302 }
303
304 let mut out = alloc::Vec::try_with_capacity(inner.len())?;
305
306 for value in inner.iter() {
307 out.try_push(value.to_value_with(&EmptyConstContext)?)?;
308 }
309
310 Ok(Self {
311 inner: out.try_into_boxed_slice()?,
312 })
313 }
314}
315
316#[cfg(feature = "alloc")]
317impl TryFrom<::rust_alloc::boxed::Box<[Value]>> for OwnedTuple {
318 type Error = alloc::Error;
319
320 #[inline]
321 fn try_from(inner: ::rust_alloc::boxed::Box<[Value]>) -> alloc::Result<Self> {
322 Ok(Self {
323 inner: alloc::Box::try_from(inner)?,
324 })
325 }
326}
327
328#[cfg(feature = "alloc")]
329impl TryFrom<::rust_alloc::boxed::Box<[ConstValue]>> for OwnedTuple {
330 type Error = RuntimeError;
331
332 fn try_from(inner: ::rust_alloc::boxed::Box<[ConstValue]>) -> Result<Self, RuntimeError> {
333 if inner.is_empty() {
334 return Ok(OwnedTuple::new());
335 }
336
337 let mut out = alloc::Vec::try_with_capacity(inner.len())?;
338
339 for value in inner.iter() {
340 out.try_push(value.to_value_with(&EmptyConstContext)?)?;
341 }
342
343 Ok(Self {
344 inner: out.try_into_boxed_slice()?,
345 })
346 }
347}
348
349impl TryFromIteratorIn<Value, Global> for OwnedTuple {
350 #[inline]
351 fn try_from_iter_in<T: IntoIterator<Item = Value>>(
352 iter: T,
353 alloc: Global,
354 ) -> alloc::Result<Self> {
355 Ok(Self {
356 inner: iter.into_iter().try_collect_in(alloc)?,
357 })
358 }
359}
360
361macro_rules! impl_tuple {
362 (0) => {
364 rune_macros::binding!(#[type_of] impl ::std::tuple::Tuple for ());
365
366 impl FromValue for () {
367 #[inline]
368 fn from_value(value: Value) -> Result<Self, RuntimeError> {
369 value.into_unit()
370 }
371 }
372
373 impl ToValue for () {
374 #[inline]
375 fn to_value(self) -> Result<Value, RuntimeError> {
376 Ok(Value::unit())
377 }
378 }
379 };
380
381 ($count:expr $(, $ty:ident $var:ident $ignore_count:expr)*) => {
382 rune_macros::binding!(#[type_of] impl <$($ty),*> ::std::tuple::Tuple for ($($ty,)*));
383
384 impl <$($ty,)*> FromValue for ($($ty,)*)
385 where
386 $($ty: FromValue,)*
387 {
388 fn from_value(value: Value) -> Result<Self, RuntimeError> {
389 let tuple = value.into_tuple_ref()?;
390
391 let [$($var,)*] = &tuple[..] else {
392 return Err(RuntimeError::new(VmErrorKind::ExpectedTupleLength {
393 actual: tuple.len(),
394 expected: $count,
395 }));
396 };
397
398 Ok(($(<$ty as FromValue>::from_value($var.clone())?,)*))
399 }
400 }
401
402 impl <$($ty,)*> FromConstValue for ($($ty,)*)
403 where
404 $($ty: FromConstValue,)*
405 {
406 fn from_const_value(value: ConstValue) -> Result<Self, RuntimeError> {
407 let tuple = value.into_tuple()?;
408
409 let [$($var,)*] = match <Box<[ConstValue; $count]>>::try_from(tuple) {
410 Ok(tuple) => Box::into_inner(tuple),
411 Err(tuple) => {
412 return Err(RuntimeError::new(VmErrorKind::ExpectedTupleLength {
413 actual: tuple.len(),
414 expected: $count,
415 }));
416 }
417 };
418
419 Ok(($(<$ty as FromConstValue>::from_const_value($var)?,)*))
420 }
421 }
422
423 impl <$($ty,)*> ToValue for ($($ty,)*)
424 where
425 $($ty: ToValue,)*
426 {
427 fn to_value(self) -> Result<Value, RuntimeError> {
428 let ($($var,)*) = self;
429 $(let $var = $var.to_value()?;)*
430 let mut vec = alloc::Vec::try_with_capacity($count)?;
431 $(vec.try_push($var)?;)*
432 let tuple = OwnedTuple::try_from(vec)?;
433 Ok(Value::try_from(tuple)?)
434 }
435 }
436
437 impl <$($ty,)*> ToConstValue for ($($ty,)*)
438 where
439 $($ty: ToConstValue,)*
440 {
441 fn to_const_value(self) -> Result<ConstValue, RuntimeError> {
442 let ($($var,)*) = self;
443 $(let $var = $var.to_const_value()?;)*
444 let mut vec = alloc::Vec::try_with_capacity($count)?;
445 $(vec.try_push($var)?;)*
446 let tuple = Box::<[ConstValue]>::try_from(vec)?;
447 Ok(ConstValue::tuple(tuple))
448 }
449 }
450 };
451}
452
453repeat_macro!(impl_tuple);
454
455impl FromValue for Box<Tuple> {
456 #[inline]
457 fn from_value(value: Value) -> Result<Self, RuntimeError> {
458 value.into_tuple()
459 }
460}
461
462impl FromValue for Ref<Tuple> {
463 #[inline]
464 fn from_value(value: Value) -> Result<Self, RuntimeError> {
465 value.into_tuple_ref()
466 }
467}
468
469impl FromValue for Mut<Tuple> {
470 #[inline]
471 fn from_value(value: Value) -> Result<Self, RuntimeError> {
472 value.into_tuple_mut()
473 }
474}
475
476impl UnsafeToRef for Tuple {
477 type Guard = RawAnyGuard;
478
479 #[inline]
480 unsafe fn unsafe_to_ref<'a>(value: Value) -> Result<(&'a Self, Self::Guard), RuntimeError> {
481 let value = Ref::from_value(value)?;
482 let (value, guard) = Ref::into_raw(value);
483 Ok((value.as_ref(), guard))
484 }
485}
486
487impl UnsafeToMut for Tuple {
488 type Guard = RawAnyGuard;
489
490 #[inline]
491 unsafe fn unsafe_to_mut<'a>(value: Value) -> Result<(&'a mut Self, Self::Guard), RuntimeError> {
492 let value = Mut::from_value(value)?;
493 let (mut value, guard) = Mut::into_raw(value);
494 Ok((value.as_mut(), guard))
495 }
496}
497
498impl TryToOwned for Tuple {
499 type Owned = OwnedTuple;
500
501 #[inline]
502 fn try_to_owned(&self) -> alloc::Result<Self::Owned> {
503 let mut vec = alloc::Vec::try_with_capacity(self.len())?;
504
505 for value in self.iter() {
506 vec.try_push(value.clone())?;
507 }
508
509 OwnedTuple::try_from(vec)
510 }
511}