Ralith / openxrs

OpenXR bindings for Rust
Apache License 2.0
282 stars 59 forks source link

Convert `T::out(...)` to trait `XrOutType::base_out(...)` #110

Open ashpil opened 2 years ago

ashpil commented 2 years ago

For my project, I found it useful to be able to reason about whether certain types were: 1) an XR type, 2) and XR output type, or 3) an XR input type. I wanted to be able to call T::out(...) on any such type. Although openxrs provided T::out(...) it did not provide any way to group types which might be an OpenXR out type.

This PR converts out to a trait (which also makes more semantic sense to me -- it's same behavior that many distinct structs share), which would let one, for example, create a function that takes in anything that can be populated by base_out. I personally found this useful when writing a different wrapper around the Result type.

A benefit of this approach is that it reduces the amount of code generated, though I'm not sure if that has measurable effects on e.g., compile time.

Ralith commented 2 years ago

Can you give an example of where it's useful to abstract over output types in general?

ashpil commented 2 years ago

Perhaps this isn't a first-class use case for this library, but I was using sys directly and writing my own high-level wrappers.

For this purpose, I created a function to aid getting values from OpenXR while properly handling the result --

fn from_sys_fn<T: xr::XrOutType>(getter: impl FnMut(&mut T) -> xr::Result) -> Result<T>

which one could use like from_sys_fn(|v| unsafe { xr::get_action_state_pose(session, &get_info, v) }). This would initialize v to its base_output() and call the function on it, and return the wrapped result.

I understand I could create something like

fn from_sys_fn(base_output: std::mem::MaybeUninit<T>, mut getter: impl FnMut(&mut T) -> xr::Result) -> Result<T>

instead, but that felt less ergonomic to me as the caller would always have to call thing.base_output() and pass it into the function.

I understand if this use case is niche and not something you're interested in directly supporting.