The safety guarantees of Rust the language around unsafe are just as good as C or Zig if you use the appropriate facilities (raw pointers, MaybeUninit, UnsafeCell/Cell, Option for nullability, Pin<> etc). Sometimes this is made unnecessarily difficult by standard library code that expects all the guarantees of ordinary Safe Rust instead of accepting more lenient input (e.g. freely aliasable &Cell<T>'s), but such cases can be addressed as they're found.

My point is that it’s easier to write correct Zig code than correct unsafe Rust. Raw pointers can be null in rust so you should use NonNull<T> but there’s aliasing rules that are easy to mess up. And difficultly with the stdlib as you mentioned.

I don’t actually mind Rust when I was able to write in safe user land, but for embedded projects I’ve had a much better time with Zig.