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
//! 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};
//!
//! let context = FpContext::new();
//! let devices = context.get_devices();
//!
//! let context = FpContext::new();
//! let devices = context.devices();
//!
//! let dev = devices.get(0).unwrap();
//! dev.open_sync(None)?;
//!
//! let template = FpPrint::new(&dev);
//! template.set_username("Bruce Banner");
//!
//! let print = dev.enroll_sync(template, None, None, None::<()>)?;
//! ```
//! # Verifying a fingerprint
//! ```rust
//! let context = FpContext::new();
//! let devices = context.devices();
//!
//! let dev = devices.get(0).unwrap();
//! dev.open_sync(None)?;
//!
//! let enrolled_print = load_print_from_file();
//!
//! let match_res = dev.verify_sync(enrolled_print, None, None, None::<()>, None)?;
//! ```
//! For more examples on how to use this crate, please refer to the [github oficial repository](https://github.com/AlvaroParker/libfprint-rs)
//! and the [documentation](https://docs.rs/libfprint-rs/latest/libfprint_rs/).
mod context;
mod device;
mod finger;
mod image;
mod print;

pub use gio::traits::CancellableExt;
/// Re-export `gio::Cancellable`, it provides a way to cancel sync operations, i.e
/// `FpDevice::enroll_sync`
pub use gio::Cancellable;
/// Re-export `glib::Error`, it provides a way to pass enroll dates to `FpPrint` metadata
pub use glib::Date as GDate;
/// Re-export `glib::Error`, it provides error handling for sync operations.
pub use glib::Error as GError;

pub use context::FpContext;
pub use device::{FpDevice, FpEnrollProgress, FpMatchCb};
pub use finger::FpFinger;
pub use image::FpImage;
pub use print::FpPrint;

#[cfg(test)]
mod tests {

    use std::io::{Read, Write};

    use crate::{FpContext, FpDevice, FpPrint};

    #[test]
    fn get_names() {
        let ctx = FpContext::new();
        let devices = ctx.devices();
        let dev = devices.get(0).unwrap();

        dev.open_sync(None).unwrap();
        let mut prints = Vec::new();

        for i in 0..3 {
            save_prints(&dev, i);
        }

        for i in 0..3 {
            let print = read_prints(i);
            prints.push(print);
        }

        let mut new_print = FpPrint::new(&dev);
        let matched = dev
            .identify_sync(&prints, None, Some(match_cb), None, Some(&mut new_print))
            .unwrap();

        if matched.is_some() {
            println!("Matched");
        } else {
            println!("Not matched");
        }
    }
    pub fn _enroll_print(dev: &FpDevice) -> FpPrint {
        let template = FpPrint::new(&dev);
        let print = dev.enroll_sync(template, None, Some(enroll_cb), None);
        print.unwrap()
    }
    pub fn save_prints(dev: &FpDevice, id: u32) {
        let template = FpPrint::new(&dev);
        let print = dev
            .enroll_sync(template, None, Some(enroll_cb), None)
            .unwrap();
        let data = print.serialize().unwrap();
        let name = format!("prints/print{}", id);
        let mut file = std::fs::File::create(name).unwrap();
        file.write_all(&data).unwrap();
    }
    pub fn read_prints(id: u32) -> FpPrint {
        let name = format!("prints/print{}", id);
        let mut file = std::fs::File::open(name).unwrap();
        let mut buf = Vec::new();
        file.read_to_end(&mut buf).unwrap();

        FpPrint::deserialize(&buf).unwrap()
    }
    pub fn enroll_cb(
        _device: &FpDevice,
        enroll_stage: i32,
        _print: Option<FpPrint>,
        _error: Option<glib::Error>,
        _data: &Option<i32>,
    ) -> () {
        println!("Enroll stage: {}", enroll_stage);
    }
    pub fn match_cb(
        _device: &FpDevice,
        matched_print: Option<FpPrint>,
        _print: FpPrint,
        _error: Option<glib::Error>,
        _data: &Option<i32>,
    ) -> () {
        if matched_print.is_some() {
            println!("Matched");
        } else {
            println!("Not matched");
        }
    }
}