ref: a2b7e1e05e07302b156ef7515cde17fcd93c443c nitrokey-rs/src d---------
Add get_struct utility function

This patch adds the internal get_struct utility function that can be
used for querying a struct with a libnitrokey function that uses an
output parameter.  Instead of this:

    let mut out = R::default();
    get_command_result(op(&mut out))?;

We can now write this:

    get_struct(|out| op(out))
Use Default::default for nitrokey-sys structs

Since version 3.6.0, nitrokey-sys derives the Default trait for all
structs.  This allows us to simplify code snippets where we have to
construct an empty struct that is then filled by nitrokey-sys.
Use NK_config struct for configuration handling

Previously, the Nitrokey configuration was represented as an array in
libnitrokey.  libnitrokey 3.6 added the NK_config struct and the
NK_{read,write}_config_struct for type-safe configuration handling.
This patch replaces the old functions with the new versions using the
NK_config struct.  This makes the RawConfig struct obsolete as it is
identical to NK_config.
Correctly free pointer to PWS status

The NK_get_password_safe_slot_status function returns a pointer to an
array that has been allocated using new[].  As we only have access to
libc’s free function, we could not free this pointer properly (using
delete[]).  libnitrokey 3.6 added the NK_free_password_safe_slot_status
function which we now use to properly free the pointer.
Use NK_device_serial_number_as_u32

Previously, we called the NK_device_serial_number function in
Device::get_serial which returned a string that we had to parse into an
unsigned integer to use with the SerialNumber struct.  libnitrokey 3.6
introduced the NK_device_serial_number_as_u32 function that returns the
serial number as an unsigned integer.  This patch replaces the call to
NK_device_serial_number with this new function.
Rename *lock fields of the Config struct

libnitrokey calls the configuration fields that set bindings for the Num
Lock, Caps Lock and Scroll Lock keys numlock, capslock, scrolllock.  Due
to a typo, scrolllock with three l was renamed to scrollock with two l
in nitrokey-rs.

To make the field names easier to read (and type) and consistent with
the typical names for these keys, this patch changes them to num_lock,
caps_lock and scroll_lock.  In the doc comments, we now use the spelling
“Num Lock”, “Caps Lock” and “Scroll Lock”.
Fix dead links in Device documentation
Fix link in User doc comment
Make *Error, Model, DeviceWrapper non-exhaustive

Previously, all enums defined by the nitrokey crate were exhaustive.
This means that adding new variants to these enums is a breaking change.
To make it possible to add new features to nitrokey-rs without breaking
compatibility, this patch marks the Error, CommandError,
CommunicationError, LibraryError, Model and DeviceWrapper enums as
Export the FirmwareVersion struct

This patch adds the FirmwareVersion struct to the re-exports in lib.rs.
Previosuly, nitrokey users where able to access FirmwareVersion values
as part of the Status struct and the Device::get_firmware_version method
but could not see its definition.
Use map_err(|_| x) instead of or_else(|_| Err(x))
Remove custom source implementation for Error

This patch removes the custom implementation of the source method of the
std::error::Error trait for the error::Error type.  This means that the
default implementation is used that always returns None.  The reason for
this change is that we already print the error message of the source
error in the Display implementation.  This leads to a duplicated error
message if both Display and source are checked, for example with
anyhow’s error formatting.

See this thread for more information:
Merge branch 'poison-error' into next

This patch series refactors the Error enum and ensures that it is Send,
Sync and 'static.  This makes sure that it is compatible with the anyhow
crate.  To achieve this, we drop the RandError variant and remove the
sync::PoisonError value from the PoisonError variant.
Ensure Error trait implementations

The anyhow crate requires that error types are error::Error, Send, Sync
and 'static.  This patch implements a simple static assertion that our
Error type implements these traits.
Remove Error::RandError variant

Since we update rand_os to version 0.2 in commit
6c138eaa850c745b97b7e48a201db0cbaad8e1e0, the random number generation
can no longer fail.  Therefore the Error::RandError variant is no longer

As we did not want to break the public API, we still kept the RandError
variant.  This patch removes the RandError variant for good.
Remove sync::PoisonError from Error::PoisonError

Previously, the Error::PoisonError contained the sync::PoisonError that
caused the error.  This is problematic as sync::PoisonError does not
implement Send, making it impossible to use the Error enum with the
anyhow crate.  At the same time, storing the sync::PoisonError is not
very useful.  If a user wants to access the poisoned lock, they can call
the force_take function.

Therefore we remove the sync::PoisonError value from the Error::
PoisonError variant.  This also allows us to simplify the
From<sync::PoisonError<…>> and From<sync::TryLockError<…>>
implementations as we no longer need to know the type of the mutex that
caused the error.

For more information, see this thread:
Use find(…) instead of skip_while(…).next()

This patch replaces calls to skip_while(…).next() for an iter::Iterator
with a call to find(…), as suggested by clippy.
Remove unused imports
Refactor string handling in util

The util module provides helper methods to deal with the C strings
returned by libnitrokey.  The current implementation has to problems:
- It causes unnecessary allocations if we only want to look at the
  string, for example in get_serial_number.
- If the conversion from a CStr to a String fails, the string pointer
  is not freed.

Therefore this patch introduces the run_with_str function that executes
a function with the string returned by libnitrokey and then makes sure
that the pointer is freed correctly.
Represent serial numbers using SerialNumber struct

In a previous commit, we changed the serial number representation from a
string to an integer.  This made it easier to compare serial numbers,
but also introduced new problems:
- Serial numbers should be formatted consistently, for example as
  "{:#010x}".  It is hard to ensure this for an integer value.
- The format of the serial number may be subject to change.  Users
  should not rely too much on the u32 representation.

Therefore we introduce a new SerialNumber struct that represents a
serial number.  Currently it only stores a u32 value.  The following
traits and functions can be used to access its value:
- FromStr for string parsing
- ToString/Display for string formatting
- as_u32 to access the underlying integer value