1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
//! Rust bindings for [libfprint](https://gitlab.freedesktop.org/libfprint/libfprint)
//!
//! This crate provides a wrapper around the libfprint library, which allows you to use fingerprint scanners in your Rust applications.
//!
//! ## Enrolling a new fingerprint
//! ```rust
//! use libfprint_rs::{FpContext, FpPrint, GError};
//!
//! let context = FpContext::new();
//! let devices = context.get_devices();
//!
//! let dev = devices.iter().next().unwrap();
//! dev.open()?;
//!
//! let template = FpPrint::new(&dev);
//! template.set_username("Bruce Banner");
//!
//! dev.enroll(template, None, None::<()>)?;
//! ```
//! ## Verifying a fingerprint
//! ```rust
//! use libfprint_rs::{FpContext, FpPrint, GError};
//! let context = FpContext::new();
//! let devices = context.get_devices();
//!
//! let dev = devices.iter().next().unwrap();
//! dev.open()?;
//!
//! let enrolled_print = load_print_from_file();
//!
//! dev.verify(enrolled_print, None, None::<()>, None)?;
//! ```
mod context;
mod device;
mod error;
mod finger;
mod image;
mod print;
pub(crate) mod utils;
pub use crate::{
context::FpContext,
// import all from device mod
device::*,
error::{GError, GErrorSource},
finger::{Finger, FpFingerStatusFlags},
image::{FpImage, FpImageData},
print::{FpPrint, SerializedPrint},
};
#[cfg(test)]
mod tests {
use std::{cell::RefCell, rc::Rc};
use crate::{context::FpContext, device::FpDevice, error::GError, print::FpPrint};
struct UserData {
_count: u32,
_name: String,
}
fn generate_print<'a>(dev: &'a FpDevice) -> FpPrint<'a> {
let user_data = UserData {
_count: 304,
_name: "Donda".into(),
};
let user_data = Rc::new(RefCell::new(user_data));
let template = FpPrint::new(&dev);
let print1 = dev
.enroll(template, Some(callback_fn), Some(user_data.clone()))
.unwrap();
println!("{}", user_data.borrow()._count);
return print1;
}
fn callback_fn(
device: &FpDevice,
completed_stages: i32,
_print: FpPrint,
_error: Option<GError>,
_user_data: &Option<Rc<RefCell<UserData>>>,
) {
if let Some(user_data) = _user_data {
user_data.borrow_mut()._count += 1;
// Mutate the user data
}
println!(
"Enrolling: {} of {}",
completed_stages,
device.get_nr_enroll_stages()
);
}
fn match_cb_function(
_device: &FpDevice, // The fingerprint scanner device
matched_print: Option<FpPrint>, // The matched print, if any.
_new_print: FpPrint, // New print scanned.
_error: Option<GError>, // Optinal error in case of an error.
match_data: &Option<Rc<RefCell<UserData>>>, // User data can be any data type.
) {
if let Some(user_data) = match_data {
user_data.borrow_mut()._count += 1;
user_data.borrow_mut()._name = "Kanye".into();
}
if matched_print.is_some() {
println!("Found matched print!");
}
}
#[test]
fn ident_test() {
let ctx = FpContext::new();
let dev = match ctx.get_devices().iter().next() {
Some(dev) => dev,
None => {
return;
}
}; // Throws errors if no device is connected
let f = dev.get_features();
println!("{:?}", f);
dev.open().unwrap(); // Open the device
let prints = vec![generate_print(&dev), generate_print(&dev)];
let mut matched_print = FpPrint::new(&dev);
matched_print.set_username("Some username should be here");
let mut new_print = FpPrint::new(&dev);
dev.identify(
prints,
Some(match_cb_function),
None,
Some(&mut matched_print),
Some(&mut new_print),
)
.unwrap();
}
}