That said, I have personally used newtypes a reasonable amount, mostly for making sure I don't mess up different kinds of database ids.
That said, I have personally used newtypes a reasonable amount, mostly for making sure I don't mess up different kinds of database ids.
It is not. `NonZeroUsize` is (though in Rust "newtype" is only a pattern or idiom), and its definition (inside of a macro which provides numeric newtypes a bunch of `impl`s) is:
pub struct NonZeroUsize(usize);
But here's String: pub struct String {
vec: Vec<u8>,
}
…which is a normal `struct` _containing_ a named `Vec<u8>`. Of the types you mentioned, only `NonZeroUsize` conforms to the pattern.1. Marking the kind of data to prevent mixing up values of different kinds. (e.g. Email)
2. Outlawing some of the values of the underlying type. (e.g. OneToFive)
I do not think it being a tuple-struct or not is important at all when deciding whether something uses the newtype pattern, as long as it has a single field.
(I was going to be cheeky here, but Git history shows you didn't write any of this part.)
There's no real difference between a 1-tuple struct and the regular struct, other than the name. So to me, it feels like either are both newtypes. But, I guess I could see some sort of argument the other way too.