Stream: general

Topic: C error code in Rust


gnzlbg (Nov 02 2018 at 14:19, on Zulip):

Is there an idiom to represent C error codes in Rust C FFI? I have a C function that returns a libc::c_int, where 0 indicates success, and the rest are error conditions.

I was thinking of representing the error conditions as #[repr(C, transparent)] struct Error(pub NonZero<c_int>);, and then using Result<???, Error> in C FFI, the question is, what do I put in () so that 0 gets translated to Ok ?

gnzlbg (Nov 02 2018 at 14:19, on Zulip):

Or shall I just use Option<Error> as the return type? (that should map 0 to None)

gnzlbg (Nov 02 2018 at 14:30, on Zulip):

Damn, NonZero<T> does not exist anymore - how can I dispatch to the appropriate NonZeroU{X} type from c_int ?

oli (Nov 02 2018 at 14:34, on Zulip):

how unstable are you willing to go?

oli (Nov 02 2018 at 14:35, on Zulip):

We do have this attribute which allows compiler internals to invent NonZero

oli (Nov 02 2018 at 14:36, on Zulip):

(and it will never be stabilized)

gnzlbg (Nov 02 2018 at 14:36, on Zulip):

Thanks, that might do. I feel it really weird that nobody raised "how do we use NonZero for libc types in the RFC that decided to kill NonZero<T> =/

oli (Nov 02 2018 at 14:37, on Zulip):

well... I think the idea is to have integer subtypes at some point. So that you can say things like i32<5..30> or whatever bikeshedded syntax we get

gnzlbg (Nov 02 2018 at 14:41, on Zulip):

the second problem is that result is not FFI safe

oli (Nov 02 2018 at 14:45, on Zulip):

well... I'd use Option in that case.

oli (Nov 02 2018 at 14:45, on Zulip):

Or create an FfiResult

gnzlbg (Nov 02 2018 at 14:47, on Zulip):

Is there a way to easily create an FfiResult type that has the same API as Result ?

kennytm (Nov 02 2018 at 14:48, on Zulip):

how can I dispatch to the appropriate NonZeroU{X} type from c_int ?

maybe you could

trait HasNonZeroUnsigned { type NonZeroUnsigned; }
impl HasNonZeroUnsigned for i32 { type NonZeroUnsigned = NonZeroU32; }
impl HasNonZeroUnsigned for isize { type NonZeroUnsigned = NonZeroUsize; }
...
type NonZeroCUInt = <c_int as HasNonZeroUnsigned>::NonZeroUnsigned;
gnzlbg (Nov 02 2018 at 14:48, on Zulip):

that's a good idea @kennytm :)

Last update: Nov 20 2019 at 12:25UTC