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
extern crate reqwest;
extern crate serde;
extern crate serde_derive;
extern crate serde_xml_rs;

pub mod structs;

use reqwest::Response;
use std::fs::File;
use std::io::copy;

pub fn scan(scanner_base_path: &str, scan_resolution: i16, destination_file: &str) {
    println!("Getting scanner capabilities...");
    let scanner_capabilities = get_scanner_capabilities(&scanner_base_path);

    let scan_settings: structs::ScanSettings = structs::ScanSettings {
        version: "2.6".to_string(),
        scan_regions: structs::ScanRegion {
            x_offset: 0,
            y_offset: 0,
            width: scanner_capabilities.platen.platen_input_caps.max_width,
            height: scanner_capabilities.platen.platen_input_caps.max_height,
            content_region_units: "escl:ThreeHundredthsOfInches".to_string(),
        },
        input_source: "Platen".to_string(),
        color_mode: "RGB24".to_string(),
        x_resolution: scan_resolution,
        y_resolution: scan_resolution,
    };

    let request_body = serde_xml_rs::to_string(&scan_settings).unwrap();

    println!("Sending scan request with DPI {}...", scan_resolution);
    let scan_response = get_scan_response(scanner_base_path, request_body);

    let download_url = format!(
        "{}/NextDocument",
        scan_response
            .headers()
            .get("location")
            .unwrap()
            .to_str()
            .unwrap()
    );

    println!("Downloading output file to {}...", destination_file);
    download_scan(&download_url, destination_file);
}

pub fn get_scanner_capabilities(scanner_base_path: &str) -> structs::ScannerCapabilities {
    let scanner_capabilities_response =
        reqwest::get(&format!("{}/ScannerCapabilities", scanner_base_path))
            .unwrap()
            .text()
            .unwrap();

    let scanner_capabilities: structs::ScannerCapabilities =
        serde_xml_rs::from_str(&scanner_capabilities_response).unwrap();

    scanner_capabilities
}

pub fn get_scan_response(scanner_base_path: &str, request_body: String) -> Response {
    let client = reqwest::Client::new();

    client
        .post(format!("{}/ScanJobs", &scanner_base_path).as_str())
        .body(format!(
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>{}",
            request_body
        ))
        .send()
        .unwrap()
}

pub fn download_scan(download_url: &str, destination_file: &str) {
    let mut file = { File::create(destination_file).unwrap() };

    let mut response = reqwest::get(download_url).unwrap();
    copy(&mut response, &mut file).unwrap();
}