pub struct Tuple<Prim: PrimitiveType = Num> { /* private fields */ }
Expand description
Tuple type.
Most generally, a tuple type consists of three fragments: start,
middle and end. Types at the start and at the end are heterogeneous,
while the middle always contains items of the same type (but the number
of these items can generally vary). A Slice
is a partial case of a tuple type;
i.e., a type with the empty start and end. Likewise, a Rust-like tuple is a tuple
that only has a start.
§Notation
A tuple type is denoted like (T, U, ...[V; _], X, Y)
, where T
and U
are types
at the start, V
is the middle type, and X
, Y
are types at the end.
The number of middle elements can be parametric, such as N
.
If a tuple only has a start, this notation collapses into Rust-like (T, U)
.
If a tuple only has a middle part (Self::as_slice()
returns Some(_)
),
it is denoted as the corresponding slice, something like [T; N]
.
§Indexing
Indexing is accessing tuple elements via an expression like xs.0
.
Tuple indexing is supported via FieldAccess
expr,
where the field name is a decimal usize
number.
The indexing support for type inference is quite limited.
For it to work, the receiver type must be known to be a tuple, and the index must be such
that the type of the corresponding element is decidable. Otherwise,
an UnsupportedIndex
error will be raised.
Tuple type | Index | Outcome |
---|---|---|
(Num, Bool) | 0 | Num |
(Num, Bool) | 1 | Bool |
(Num, Bool) | 2 | Hard error; the index is out of bounds. |
Num | 0 | Hard error; only tuples can be indexed. |
[Num; _] | 0 | Error; the slice may be empty. |
[Num; _ + 1] | 0 | Num ; the slice is guaranteed to have 0th element. |
(Bool, ...[Num; _]) | 0 | Bool |
(Bool, ...[Num; _]) | 1 | Error; the slice part may be empty. |
(...[Num; _], Bool) | 0 | Error; cannot decide if the result is Num or Bool . |
§Examples
Simple tuples can be created using the From
trait. Complex tuples can be created
via Self::new()
.
let simple_tuple = Tuple::from(vec![Type::NUM, Type::BOOL]);
assert_matches!(simple_tuple.parts(), ([_, _], None, []));
assert!(simple_tuple.as_slice().is_none());
assert_eq!(simple_tuple.to_string(), "(Num, Bool)");
let slice_tuple = Tuple::from(
Type::NUM.repeat(UnknownLen::param(0)),
);
assert_matches!(slice_tuple.parts(), ([], Some(_), []));
assert!(slice_tuple.as_slice().is_some());
assert_eq!(slice_tuple.to_string(), "[Num; N]");
let complex_tuple = Tuple::new(
vec![Type::NUM],
Type::NUM.repeat(UnknownLen::param(0)),
vec![Type::BOOL, Type::param(0)],
);
assert_matches!(complex_tuple.parts(), ([_], Some(_), [_, _]));
assert_eq!(complex_tuple.to_string(), "(Num, ...[Num; N], Bool, 'T)");
Implementations§
Source§impl<Prim: PrimitiveType> Tuple<Prim>
impl<Prim: PrimitiveType> Tuple<Prim>
Sourcepub fn new(
start: Vec<Type<Prim>>,
middle: Slice<Prim>,
end: Vec<Type<Prim>>,
) -> Self
pub fn new( start: Vec<Type<Prim>>, middle: Slice<Prim>, end: Vec<Type<Prim>>, ) -> Self
Creates a new complex tuple.
Sourcepub fn as_slice(&self) -> Option<&Slice<Prim>>
pub fn as_slice(&self) -> Option<&Slice<Prim>>
Returns this tuple as slice if it fits (has no start or end components).
Sourcepub fn parts(&self) -> (&[Type<Prim>], Option<&Slice<Prim>>, &[Type<Prim>])
pub fn parts(&self) -> (&[Type<Prim>], Option<&Slice<Prim>>, &[Type<Prim>])
Returns shared references to the parts comprising this tuple: start, middle, and end.
Sourcepub fn parts_mut(
&mut self,
) -> (&mut [Type<Prim>], Option<&mut Slice<Prim>>, &mut [Type<Prim>])
pub fn parts_mut( &mut self, ) -> (&mut [Type<Prim>], Option<&mut Slice<Prim>>, &mut [Type<Prim>])
Returns exclusive references to the parts comprising this tuple: start, middle, and end.
Sourcepub fn len(&self) -> TupleLen
pub fn len(&self) -> TupleLen
Returns the length of this tuple.
§Examples
let tuple = Tuple::from(vec![Type::NUM, Type::BOOL]);
assert_eq!(tuple.len(), TupleLen::from(2));
let slice = Slice::new(Type::NUM, UnknownLen::param(0));
let tuple = Tuple::from(slice.clone());
assert_eq!(tuple.len(), TupleLen::from(UnknownLen::param(0)));
let tuple = Tuple::new(vec![], slice, vec![Type::BOOL]);
assert_eq!(tuple.len(), UnknownLen::param(0) + 1);
Sourcepub fn element_types(
&self,
) -> impl Iterator<Item = (TupleIndex, &Type<Prim>)> + '_
pub fn element_types( &self, ) -> impl Iterator<Item = (TupleIndex, &Type<Prim>)> + '_
Iterates over all distinct elements in this tuple. The iteration is performed in order.
§Examples
let complex_tuple = Tuple::new(
vec![Type::NUM],
Slice::new(Type::NUM, UnknownLen::param(0)),
vec![Type::BOOL, Type::param(0)],
);
let elements: Vec<_> = complex_tuple.element_types().collect();
assert_eq!(elements, [
(TupleIndex::Start(0), &Type::NUM),
(TupleIndex::Middle, &Type::NUM),
(TupleIndex::End(0), &Type::BOOL),
(TupleIndex::End(1), &Type::param(0)),
]);
Trait Implementations§
Source§impl<Prim: PrimitiveType> Display for Tuple<Prim>
impl<Prim: PrimitiveType> Display for Tuple<Prim>
Source§impl<Prim: PrimitiveType> PartialEq for Tuple<Prim>
impl<Prim: PrimitiveType> PartialEq for Tuple<Prim>
Auto Trait Implementations§
impl<Prim> Freeze for Tuple<Prim>
impl<Prim = Num> !RefUnwindSafe for Tuple<Prim>
impl<Prim> Send for Tuple<Prim>
impl<Prim> Sync for Tuple<Prim>
impl<Prim> Unpin for Tuple<Prim>where
Prim: Unpin,
impl<Prim = Num> !UnwindSafe for Tuple<Prim>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.Source§impl<T> PipeAsRef for T
impl<T> PipeAsRef for T
Source§impl<T> PipeBorrow for T
impl<T> PipeBorrow for T
Source§impl<T> PipeDeref for T
impl<T> PipeDeref for T
Source§impl<T> PipeRef for T
impl<T> PipeRef for T
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap<F, R>(self, func: F) -> Selfwhere
F: FnOnce(&Self) -> R,
fn tap<F, R>(self, func: F) -> Selfwhere
F: FnOnce(&Self) -> R,
Source§fn tap_dbg<F, R>(self, func: F) -> Selfwhere
F: FnOnce(&Self) -> R,
fn tap_dbg<F, R>(self, func: F) -> Selfwhere
F: FnOnce(&Self) -> R,
tap
in debug builds, and does nothing in release builds.Source§fn tap_mut<F, R>(self, func: F) -> Selfwhere
F: FnOnce(&mut Self) -> R,
fn tap_mut<F, R>(self, func: F) -> Selfwhere
F: FnOnce(&mut Self) -> R,
Source§fn tap_mut_dbg<F, R>(self, func: F) -> Selfwhere
F: FnOnce(&mut Self) -> R,
fn tap_mut_dbg<F, R>(self, func: F) -> Selfwhere
F: FnOnce(&mut Self) -> R,
tap_mut
in debug builds, and does nothing in release builds.Source§impl<T, U> TapAsRef<U> for Twhere
U: ?Sized,
impl<T, U> TapAsRef<U> for Twhere
U: ?Sized,
Source§fn tap_ref<F, R>(self, func: F) -> Self
fn tap_ref<F, R>(self, func: F) -> Self
Source§fn tap_ref_dbg<F, R>(self, func: F) -> Self
fn tap_ref_dbg<F, R>(self, func: F) -> Self
tap_ref
in debug builds, and does nothing in release builds.Source§fn tap_ref_mut<F, R>(self, func: F) -> Self
fn tap_ref_mut<F, R>(self, func: F) -> Self
Source§impl<T, U> TapBorrow<U> for Twhere
U: ?Sized,
impl<T, U> TapBorrow<U> for Twhere
U: ?Sized,
Source§fn tap_borrow<F, R>(self, func: F) -> Self
fn tap_borrow<F, R>(self, func: F) -> Self
Source§fn tap_borrow_dbg<F, R>(self, func: F) -> Self
fn tap_borrow_dbg<F, R>(self, func: F) -> Self
tap_borrow
in debug builds, and does nothing in release builds.Source§fn tap_borrow_mut<F, R>(self, func: F) -> Self
fn tap_borrow_mut<F, R>(self, func: F) -> Self
Source§impl<T> TapDeref for T
impl<T> TapDeref for T
Source§fn tap_deref_dbg<F, R>(self, func: F) -> Self
fn tap_deref_dbg<F, R>(self, func: F) -> Self
tap_deref
in debug builds, and does nothing in release builds.Source§fn tap_deref_mut<F, R>(self, func: F) -> Self
fn tap_deref_mut<F, R>(self, func: F) -> Self
self
for modification.