Author here. Both my Zig code and the Rust peripheral access crate model the pins as distinct types, which I think is correct --- the pins have different memory addresses and sometimes (depending on the microcontroller) distinct sets of controlling registers.
The tricky part in Rust is how to make things generic across distinct types.
Zig's comptime lets you sort of "duck type" it (but with compile-time checking that all of the methods exist, etc.), whereas Rust requires that you explicitly introduce a trait and implement trait methods across the types.
The embedded HAL crates do this with extensive use of macros, for example: https://github.com/nrf-rs/nrf-hal/blob/aae17943efc24baffe30b...
This solution makes sense given the constraints of Rust, but there's quite a cost in terms of compiler time and cognitive overhead to understand what is going on.
(Aside: I didn't use the HAL in my Rust firmware, that's a higher layer of abstraction; I only used the PAC crates.)