iTrooz / efivar-rs

EFI boot manager tool written in Rust
MIT License
22 stars 7 forks source link

Expose platform-dependent low-level implementations as separate crates #13

Open MOZGIII opened 5 years ago

MOZGIII commented 5 years ago

As a way for the future improvements, I'd love to have access to low-level implementation details, for the cases where I have to perform low-level operations.

I'd propose the following structure:

/
/efivar              <- limited high-level interface unifiying/abstracting all the low-level interfaces
/efivar-winapi       <- winapi implementation (windows)
/efivar-efivarfs     <- efivarfs implementation (linux)
/efivar-efivar       <- efivar implementation (linux)
/efivar-nvram        <- nvram implementation (macOS)

All the low-level crates should provide the interface that makes the most sense for a particular implementation. For example, windows implementation would just provide rust-safe wrappers for read var and write var operations, without any boilterplate like VarManager etc. To be more specifc, for write variable functionality only a thin rust-safety wrapper around SetFirmwareEnvironmentVariableExW would be required.

For the high-level efivar the idea of the interface would be the same, but the internal implementation would utilize other crates with the low-level implementations and wrap them up for the unified API.

This would be useful to build up a more feature-full rust crates ecosystem for working with efi variables.

alixinne commented 5 years ago

I am curious, while it's true that the efivar wrappers could probably be thinner, what would be a use-case for direct access to the winapi/efivarfs/nvram implementations?

MOZGIII commented 5 years ago

I don't have a concrete use case example in mind, but the rationale for providing low level implementations is to let users to consume the API in ways different to those that the unified wrapper would allow. An example for that would be to allow user to get just the attributes for a var with an efivar (not efivarfs) backend, or enumerate both the names and values in a single operation (via nvram command on macOS). The benefit of this approach is that it'd be possible to provide a low-overhead, as close to the backend as possible, implementations while also providing easy to use but limited (to the "lowest common denominator" of the all backends) unified API.

In addition, the low-level parts should be able to evolve individually, and gain additional features, that are not currently implemented because they're not required for the unified API (or for various other reasons). Actually, this is where I see the most value from the split-up.