logoalt Hacker News

tialaramextoday at 1:27 PM0 repliesview on HN

It depends

Suppose there's a C library libape which implements monkeys you need in your software. There's a C API where we pass a pointer to a valid monkey and a 32-bit unsigned integer which controls how delicious bananas are. Any 32-bit unsigned integer is valid here, except zero because monkeys always think bananas are at least somewhat delicious, and there's no return value.

Our Rust wrapper probably has Monkey as a type, wrapping one of those valid monkey pointers we mentioned, and so our wrapper for that API call is some unsafe code which just calls the C with this monkey pointer and a non-zero unsigned 32-bit integer which in Rust is just the type NonZeroU32 and we're done. That's a single line, the unsafety checking was all done in Rust's type system, every Monkey has a valid monkey pointer, every NonZeroU32 is (as its name suggests) a non-zero unsigned 32-bit integer.

Now on the other hand, maybe we're wrapping code which takes a char * pointer intended to point at some zero terminated ISO-8859-1 encoded text. That Rust wrapper would be responsible for this translation and maybe you do that work in the wrapper function. But, if you had sixty calls like that, probably you make a Rust type for this problem named like Iso8859dash1Text and then those unsafe calls don't have a lot of boilerplate because all that boilerplate (which is probably even safe Rust depending on how exactly you do it) lives in this Iso8859dash1Text type you made. And that's also a useful model if later you discover the C library lied and it's not ISO-8859-1 it's really Windows Codepage 1252 ...