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