How can I ensure that a Rust vector only contains alternating types?

To store alternating types in a way that the type system enforces and has reasonable efficiency, you can use a tuple: Vec<(X, Y)>.

Your situation also requires

  • Storing an extra leading value in an Option to handle starting with Y
  • Storing an extra trailing value in an Option to handle ending with X
use either::Either; // 1.5.2
use std::iter;

#[derive(Debug, Default)]
struct Data<X, Y> {
    head: Option<Y>,
    pairs: Vec<(X, Y)>,
    tail: Option<X>,
}

impl<X, Y> Data<X, Y> {
    fn iter(&self) -> impl Iterator<Item = Either<&X, &Y>> {
        let head = self.head.iter().map(Either::Right);

        let pairs = self.pairs.iter().flat_map(|(a, b)| {
            let a = iter::once(Either::Left(a));
            let b = iter::once(Either::Right(b));
            a.chain(b)
        });

        let tail = self.tail.iter().map(Either::Left);

        head.chain(pairs).chain(tail)
    }
}

That being said, you are going to have ergonomic issues somewhere. For example, you can't just push an Either<X, Y> because the previously pushed value might be of the same type. Creating the entire structure at once might be the simplest direction:

#[derive(Debug)]
struct A;
#[derive(Debug)]
struct B;

fn main() {
    let data = Data {
        head: Some(B),
        pairs: vec![(A, B)],
        tail: None,
    };

    println!("{:?}", data.iter().collect::<Vec<_>>());
}