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
43pub use gio::traits::CancellableExt;
44/// Re-export `gio::Cancellable`, it provides a way to cancel sync operations, i.e
45/// `FpDevice::enroll_sync`
46pub use gio::Cancellable;
47/// Re-export `glib::Error`, it provides a way to pass enroll dates to `FpPrint` metadata
48pub use glib::Date as GDate;
49/// Re-export `glib::Error`, it provides error handling for sync operations.
50pub use glib::Error as GError;
51
52pub use context::FpContext;
53pub use device::{FpDevice, FpEnrollProgress, FpMatchCb};
54pub use finger::FpFinger;
55pub use image::FpImage;
56pub use print::FpPrint;
57
58#[cfg(test)]
59mod tests {
60
61    use std::io::{Read, Write};
62
63    use crate::{FpContext, FpDevice, FpPrint};
64
65    #[test]
66    fn get_names() {
67        let ctx = FpContext::new();
68        let devices = ctx.devices();
69        let dev = devices.get(0).unwrap();
70
71        dev.open_sync(None).unwrap();
72        let mut prints = Vec::new();
73
74        for i in 0..3 {
75            save_prints(&dev, i);
76        }
77
78        for i in 0..3 {
79            let print = read_prints(i);
80            prints.push(print);
81        }
82
83        let mut new_print = FpPrint::new(&dev);
84        let matched = dev
85            .identify_sync(&prints, None, Some(match_cb), None, Some(&mut new_print))
86            .unwrap();
87
88        if matched.is_some() {
89            println!("Matched");
90        } else {
91            println!("Not matched");
92        }
93    }
94    pub fn _enroll_print(dev: &FpDevice) -> FpPrint {
95        let template = FpPrint::new(&dev);
96        let print = dev.enroll_sync(template, None, Some(enroll_cb), None);
97        print.unwrap()
98    }
99    pub fn save_prints(dev: &FpDevice, id: u32) {
100        let template = FpPrint::new(&dev);
101        let print = dev
102            .enroll_sync(template, None, Some(enroll_cb), None)
103            .unwrap();
104        let data = print.serialize().unwrap();
105        let name = format!("prints/print{}", id);
106        let mut file = std::fs::File::create(name).unwrap();
107        file.write_all(&data).unwrap();
108    }
109    pub fn read_prints(id: u32) -> FpPrint {
110        let name = format!("prints/print{}", id);
111        let mut file = std::fs::File::open(name).unwrap();
112        let mut buf = Vec::new();
113        file.read_to_end(&mut buf).unwrap();
114
115        FpPrint::deserialize(&buf).unwrap()
116    }
117    pub fn enroll_cb(
118        _device: &FpDevice,
119        enroll_stage: i32,
120        _print: Option<FpPrint>,
121        _error: Option<glib::Error>,
122        _data: &Option<i32>,
123    ) -> () {
124        println!("Enroll stage: {}", enroll_stage);
125    }
126    pub fn match_cb(
127        _device: &FpDevice,
128        matched_print: Option<FpPrint>,
129        _print: FpPrint,
130        _error: Option<glib::Error>,
131        _data: &Option<i32>,
132    ) -> () {
133        if matched_print.is_some() {
134            println!("Matched");
135        } else {
136            println!("Not matched");
137        }
138    }
139}