nitrokey 0.9.0

Bindings to libnitrokey for communication with Nitrokey devices
Documentation
// Copyright (C) 2018-2020 Robin Krahl <robin.krahl@ireas.org>
// SPDX-License-Identifier: MIT

use crate::device::{Device, Model, Status};
use crate::error::Error;
use crate::otp::GenerateOtp;
use crate::util::get_struct;

/// A Librem Key device without user or admin authentication.
///
/// Use the [`connect`][] method to obtain an instance wrapper or the [`connect_librem`] method to
/// directly obtain an instance.  If you want to execute a command that requires user or admin
/// authentication, use [`authenticate_admin`][] or [`authenticate_user`][].
///
/// # Examples
///
/// Authentication with error handling:
///
/// ```no_run
/// use nitrokey::{Authenticate, User, Librem};
/// # use nitrokey::Error;
///
/// fn perform_user_task<'a>(device: &User<'a, Librem<'a>>) {}
/// fn perform_other_task(device: &Librem) {}
///
/// # fn try_main() -> Result<(), Error> {
/// let mut manager = nitrokey::take()?;
/// let device = manager.connect_librem()?;
/// let device = match device.authenticate_user("123456") {
///     Ok(user) => {
///         perform_user_task(&user);
///         user.device()
///     },
///     Err((device, err)) => {
///         eprintln!("Could not authenticate as user: {}", err);
///         device
///     },
/// };
/// perform_other_task(&device);
/// #     Ok(())
/// # }
/// ```
///
/// [`authenticate_admin`]: trait.Authenticate.html#method.authenticate_admin
/// [`authenticate_user`]: trait.Authenticate.html#method.authenticate_user
/// [`connect`]: struct.Manager.html#method.connect
/// [`connect_librem`]: struct.Manager.html#method.connect_librem
#[derive(Debug)]
pub struct Librem<'a> {
    manager: Option<&'a mut crate::Manager>,
}

impl<'a> Librem<'a> {
    pub(crate) fn new(manager: &'a mut crate::Manager) -> Librem<'a> {
        Librem {
            manager: Some(manager),
        }
    }
}

impl<'a> Drop for Librem<'a> {
    fn drop(&mut self) {
        unsafe {
            nitrokey_sys::NK_logout();
        }
    }
}

impl<'a> Device<'a> for Librem<'a> {
    fn into_manager(mut self) -> &'a mut crate::Manager {
        self.manager.take().unwrap()
    }

    fn get_model(&self) -> Model {
        Model::Librem
    }

    fn get_status(&self) -> Result<Status, Error> {
        get_struct(|out| unsafe { nitrokey_sys::NK_get_status(out) })
    }
}

impl<'a> GenerateOtp for Librem<'a> {}