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, Hasher, Mut,
17 ProtocolCaller, RawAnyGuard, Ref, RuntimeError, ToConstValue, ToValue, UnsafeToMut,
18 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)]
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 Deref for OwnedTuple {
181 type Target = Tuple;
182
183 #[inline]
184 fn deref(&self) -> &Self::Target {
185 Tuple::new(&self.inner)
186 }
187}
188
189impl DerefMut for OwnedTuple {
190 #[inline]
191 fn deref_mut(&mut self) -> &mut Self::Target {
192 Tuple::new_mut(&mut self.inner)
193 }
194}
195
196impl AsRef<Tuple> for OwnedTuple {
197 #[inline]
198 fn as_ref(&self) -> &Tuple {
199 self
200 }
201}
202
203impl AsMut<Tuple> for OwnedTuple {
204 #[inline]
205 fn as_mut(&mut self) -> &mut Tuple {
206 self
207 }
208}
209
210impl Borrow<Tuple> for OwnedTuple {
211 #[inline]
212 fn borrow(&self) -> &Tuple {
213 self
214 }
215}
216
217impl Default for OwnedTuple {
218 fn default() -> Self {
219 Self::new()
220 }
221}
222
223impl TryClone for OwnedTuple {
224 #[inline]
225 fn try_clone(&self) -> alloc::Result<Self> {
226 Ok(Self {
227 inner: self.inner.try_clone()?,
228 })
229 }
230
231 #[inline]
232 fn try_clone_from(&mut self, source: &Self) -> alloc::Result<()> {
233 self.inner.try_clone_from(&source.inner)
234 }
235}
236
237impl fmt::Debug for OwnedTuple {
238 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
239 write!(f, "(")?;
240
241 let mut it = self.iter();
242 let last = it.next_back();
243
244 for el in it {
245 write!(f, "{el:?}, ")?;
246 }
247
248 if let Some(last) = last {
249 write!(f, "{last:?}")?;
250 }
251
252 write!(f, ")")?;
253 Ok(())
254 }
255}
256
257impl TryFrom<rust_alloc::vec::Vec<Value>> for OwnedTuple {
258 type Error = alloc::Error;
259
260 #[inline]
261 fn try_from(vec: rust_alloc::vec::Vec<Value>) -> Result<Self, Self::Error> {
262 Ok(Self {
263 inner: alloc::Box::try_from(vec.into_boxed_slice())?,
264 })
265 }
266}
267
268impl TryFrom<alloc::Vec<Value>> for OwnedTuple {
269 type Error = alloc::Error;
270
271 #[inline]
272 fn try_from(vec: alloc::Vec<Value>) -> Result<Self, Self::Error> {
273 Ok(Self {
274 inner: vec.try_into_boxed_slice()?,
275 })
276 }
277}
278
279impl<const N: usize> TryFrom<[Value; N]> for OwnedTuple {
280 type Error = alloc::Error;
281
282 #[inline]
283 fn try_from(values: [Value; N]) -> Result<Self, Self::Error> {
284 Ok(Self {
285 inner: values.try_into()?,
286 })
287 }
288}
289
290impl From<alloc::Box<[Value]>> for OwnedTuple {
291 #[inline]
292 fn from(inner: alloc::Box<[Value]>) -> Self {
293 Self { inner }
294 }
295}
296
297impl TryFrom<alloc::Box<[ConstValue]>> for OwnedTuple {
298 type Error = RuntimeError;
299
300 fn try_from(inner: alloc::Box<[ConstValue]>) -> Result<Self, RuntimeError> {
301 if inner.is_empty() {
302 return Ok(OwnedTuple::new());
303 }
304
305 let mut out = alloc::Vec::try_with_capacity(inner.len())?;
306
307 for value in inner.iter() {
308 out.try_push(value.to_value_with(&EmptyConstContext)?)?;
309 }
310
311 Ok(Self {
312 inner: out.try_into_boxed_slice()?,
313 })
314 }
315}
316
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
328impl TryFrom<rust_alloc::boxed::Box<[ConstValue]>> for OwnedTuple {
329 type Error = RuntimeError;
330
331 #[inline]
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 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}