The prevention of flipping ids in #rustlang

Given I have a file of document id and text unit id. For example:

doc-id, text-unit-ids
1,100,200,300
2,50,8,1,6

I want to keep them in a list of doc-id, text-unit-id pairs. For example:

1,100
1,200
1,300
2,50
2,8
2,1
2,6

So I defined my variable in Rust, as follow:

let word_id_tu_ids: Vec<(u32, u32)> = vec![];

Sometimes I have a problem that I flipped them. I put a pair of text-unit-id and doc-id instead of text-unit-it and doc-id. For example, I put 100,1 instead of 100,1.

By (u32, u32), the Rust compiler cannot help me. So I tried:

type WordId = u32;
type DocId = u32;

fn push(w: WordId, d: DocId) {
    let mut v: Vec<(WordId, DocId)> = vec![];
    v.push((d, w));
}

It didn't help. So I tried struct instead.

struct WordId(u32);
struct DocId(u32);

fn push(w: WordId, d: DocId) {
    let mut v: Vec<(WordId, DocId)> = vec![];
    v.push((d, w));
}

Now the compiler can detect the error. However, maybe it is not clear to human eyes. So I defined another struct.

struct WordId(u32);
struct DocId(u32);

struct WordIdDocId {
    word_id: WordId,
    doc_id: DocId,
}

fn push(w: WordId, d: DocId) {
    let mut v: Vec<WordIdDocId> = vec![];
    v.push(WordIdDocId {word_id: w, doc_id: d});
}

Now it is clear to human eyes and the compiler. Anyways, is it what people call over-engineering? What if I want to:

let u = w + 1;

We can do it in Rust, but the code is going to be even longer.