You can't avoid traits and generics entirely, but you can get by with far less than the norm (which is simpler, has some powerful code-reading advantages, and some expressiveness drawbacks). Personally I keep using Vec<T> and other hashmaps, I generally prefer match over .value_or().map(...) functional-style Option/Iterator chaining (though my opinion is unwelcome in some "oh-so-accepting" Rust spaces), prefer type methods over trait methods (which you can't even call unless you `use` the trait into scope), etc. Unfortunately when building generic data structures, you sometimes need complex lifetime and trait Send/Sync/Sized bounds (but I try to switch approaches and sometimes write duplicated code, whenever a particular abstraction approach starts requiring complex HRTBs and such).
You can't avoid using generics, but you can avoid writing generic data structures if the standard library is sufficient and your application won't benefit from de-duplicating code shared between similar structs.
It depends on the use case. The short and simple answer is avoid libs that rely heavily on them, and use structs and enums. This gets into the area of application code vs libraries. A simple example, for say, a struct used to interact with a bus on a MCU is to use a `I2c` struct, instead of `I2c<Output<OpenDrain<PA5<Af5>>>, Output<OpenDrain<PA6<AF5>>>>` etc. God help you if the library that uses the latter doesn't document it using examples, because the auto-generated Rust docs won't help.