n.to_u16() is redundant when we already have u16::from(n). Both convey the same information. The difference is using From leans on a trait, which to me is more idiomatic, and permits things like using generics or associated types with bounds for convertible types, something I just used the other day as it were for this specific case.
Furthermore:
u16::from(n)
…already has impls for: bool, u8, NonZeroU16
https://doc.rust-lang.org/std/primitive.u16.html#impl-From<bool>
u16::try_from(n)
…already has impls for: i8, i16, i32, i64, i128, isize, u32, u64, u128, usize
https://doc.rust-lang.org/std/primitive.u16.html#impl-TryFrom<i32>
What you are proposing is redundant, less idiomatic, and as @josh noted results in an explosion of complexity.
This is a slippery slope argument. The usage of From / TryFrom mentioned here is specifically for the purpose of type conversions, which is exactly what you were originally asking about, exactly as these traits are intended to use, and many of these type conversions are already impl’d for these types.
No one is proposing they be used to things which have side effects or to create network packets. Yes, that would be bad, but it’s also irrelevant for this use case.