Looking for anyone who has tried this approach and can either provide a "won't work" or "good idea" experience.
Background
I'm currently working on a crate & app which (initially) targets windows and includes custom ffi bindings to provide hardware access.[1]
I code on linux and cross-compile, while I can set up rust-analyzer to work with an alternative target, I'd also like to no-run rather than ignore doc-tests and ideally create & run unit tests.
Idea
I've just started to work out the following pattern:
// src/win/bindings/mod.rs
mod bindgen;
mod mocks;
#[cfg(all(target_family = "windows", not(any(test, doc))))]
pub(crate) use bindgen::*;
#[cfg(any(test, doc, not(target_family = "windows")))]
// ffi functions
pub(crate) use mocks::{
CloseHandle, CreateFile2, ...
};
#[cfg(any(test, doc, not(target_family = "windows")))]
// ffi types & consts
pub use bindgen::{
CDDA, CDROM_READ_TOC_EX, ...
};
That way I can:
- have examples in my docs, which compile, even though they use functionality currently only available on windows (done)
- create unit tests of functionality which relies on hardware access (I can only get so far by splitting IO & processing into separate functions) and error-handling in the IO-functions, by providing concrete results from the mocks. (next step todo)
- still create a
pub mod linux;in the future with a similar structure and providecfg(target-family = ...)-gated,pub usere-exports inlib.rsfor consumers (sometime in the future)
Help, please
Has anyone tried this before? Is it a usually pattern I've just not noticed? Is it fundamentally broken and I'll only notice that after quite a bit of work? ...
Thanks in advance!
in my case I'm working on reading audio Cds and need specific access to the hardware to do this via windows APIs rather than raw SCSI ↩︎