libfprint_rs/
lib.rs

1//! Rust bindings for [libfprint](https://gitlab.freedesktop.org/libfprint/libfprint).
2//!
3//! This crate provides a wrapper around the libfprint library, which allows you to use fingerprint scanners in your Rust applications.
4//!
5//! # Enrolling a new fingerprint
6//! ```rust
7//! use libfprint_rs::{FpContext, FpPrint};
8//!
9//! let context = FpContext::new();
10//! let devices = context.get_devices();
11//!
12//! let context = FpContext::new();
13//! let devices = context.devices();
14//!
15//! let dev = devices.get(0).unwrap();
16//! dev.open_sync(None)?;
17//!
18//! let template = FpPrint::new(&dev);
19//! template.set_username("Bruce Banner");
20//!
21//! let print = dev.enroll_sync(template, None, None, None::<()>)?;
22//! ```
23//! # Verifying a fingerprint
24//! ```rust
25//! let context = FpContext::new();
26//! let devices = context.devices();
27//!
28//! let dev = devices.get(0).unwrap();
29//! dev.open_sync(None)?;
30//!
31//! let enrolled_print = load_print_from_file();
32//!
33//! let match_res = dev.verify_sync(enrolled_print, None, None, None::<()>, None)?;
34//! ```
35//! For more examples on how to use this crate, please refer to the [github oficial repository](https://github.com/AlvaroParker/libfprint-rs)
36//! and the [documentation](https://docs.rs/libfprint-rs/latest/libfprint_rs/).
37mod context;
38mod device;
39mod finger;
40mod image;
41mod print;
42
43/// Re-export `gio::Cancellable`, it provides a way to cancel sync operations, i.e
44/// `FpDevice::enroll_sync`
45pub use gio::Cancellable;
46/// Re-export `glib::Error`, it provides a way to pass enroll dates to `FpPrint` metadata
47pub use glib::Date as GDate;
48/// Re-export `glib::Error`, it provides error handling for sync operations.
49pub use glib::Error as GError;
50
51pub use context::FpContext;
52pub use device::{FpDevice, FpEnrollProgress, FpMatchCb};
53pub use finger::FpFinger;
54pub use image::FpImage;
55pub use print::FpPrint;
56
57#[cfg(test)]
58mod tests {
59
60    use std::io::{Read, Write};
61
62    use crate::{FpContext, FpDevice, FpPrint};
63
64    #[test]
65    fn get_names() {
66        let ctx = FpContext::new();
67        let devices = ctx.devices();
68        let dev = devices.first().unwrap();
69
70        dev.open_sync(None).unwrap();
71        let mut prints = Vec::new();
72
73        for i in 0..3 {
74            save_prints(dev, i);
75        }
76
77        for i in 0..3 {
78            let print = read_prints(i);
79            prints.push(print);
80        }
81
82        let mut new_print = FpPrint::new(dev);
83        let matched = dev
84            .identify_sync(&prints, None, Some(match_cb), None, Some(&mut new_print))
85            .unwrap();
86
87        if matched.is_some() {
88            println!("Matched");
89        } else {
90            println!("Not matched");
91        }
92    }
93    pub fn _enroll_print(dev: &FpDevice) -> FpPrint {
94        let template = FpPrint::new(dev);
95        let print = dev.enroll_sync(template, None, Some(enroll_cb), None);
96        print.unwrap()
97    }
98    pub fn save_prints(dev: &FpDevice, id: u32) {
99        let template = FpPrint::new(dev);
100        let print = dev
101            .enroll_sync(template, None, Some(enroll_cb), None)
102            .unwrap();
103        let data = print.serialize().unwrap();
104        let name = format!("prints/print{}", id);
105        let mut file = std::fs::File::create(name).unwrap();
106        file.write_all(&data).unwrap();
107    }
108    pub fn read_prints(id: u32) -> FpPrint {
109        let name = format!("prints/print{}", id);
110        let mut file = std::fs::File::open(name).unwrap();
111        let mut buf = Vec::new();
112        file.read_to_end(&mut buf).unwrap();
113
114        FpPrint::deserialize(&buf).unwrap()
115    }
116    pub fn enroll_cb(
117        _device: &FpDevice,
118        enroll_stage: i32,
119        _print: Option<FpPrint>,
120        _error: Option<glib::Error>,
121        _data: &Option<i32>,
122    ) {
123        println!("Enroll stage: {}", enroll_stage);
124    }
125    pub fn match_cb(
126        _device: &FpDevice,
127        matched_print: Option<FpPrint>,
128        _print: FpPrint,
129        _error: Option<glib::Error>,
130        _data: &Option<i32>,
131    ) {
132        if matched_print.is_some() {
133            println!("Matched");
134        } else {
135            println!("Not matched");
136        }
137    }
138}