You can use size_of on the tuple directly, but there's no way to know the tuple's size if you just have its fields. This is because Rust represents tuples using the #[repr(Rust)] representation, so there aren't any guarantees for how tuples are laid out.
Note that this will give you the size of the tuple's leaf nodes on the stack, and doesn't dereference heap allocations. It could also be implemented as an associate constant instead of a method with no loss of generality.
We can be more general using min_specialization (though full generality requires variadics):
#![feature(min_specialization)]
use std::mem;
trait Tuple {
fn size() -> usize;
}
impl<T> Tuple for T {
default fn size() -> usize {
mem::size_of::<T>()
}
}
macro_rules! impl_tuple {
( $first:ident, $($rest:ident,)* ) => {
impl<$first, $($rest,)*> Tuple for ($first, $($rest,)*) {
fn size() -> usize {
<$first as Tuple>::size() $(+ <$rest as Tuple>::size())*
}
}
impl_tuple!( $($rest,)* );
};
() => {
// `()`, the empty tuple, is guaranteed to be zero-sized, so it's `size_of()`
// is always 0 - what we want for it. So need no for a manual impl.
};
}
impl_tuple!(
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O,
);
pub fn tuple_size<T>() -> usize {
<T as Tuple>::size()
}