add command options

This commit is contained in:
Magnus Ulimoen 2020-07-25 22:45:04 +02:00
parent 4fa167eb2a
commit 56aa9635c3
2 changed files with 48 additions and 13 deletions

View File

@ -7,6 +7,7 @@ edition = "2018"
[dependencies] [dependencies]
sane-sys = { path = "sane-sys" } sane-sys = { path = "sane-sys" }
image = "0.23.7" image = "0.23.7"
gumdrop = "0.8.0"
[workspace] [workspace]
members = [ members = [

View File

@ -3,6 +3,8 @@
use sane_sys::*; use sane_sys::*;
use std::ffi::CStr; use std::ffi::CStr;
use gumdrop::Options;
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
enum Error { enum Error {
Status(SANE_Status), Status(SANE_Status),
@ -284,7 +286,9 @@ impl Opt {
})) }))
} }
fn get_string(&self) -> Result<String, Error> { fn get_string(&self) -> Result<String, Error> {
assert_eq!(self.descriptor.type_(), SANE_Value_Type_SANE_TYPE_STRING); if self.descriptor.type_() != SANE_Value_Type_SANE_TYPE_STRING {
return Err(Error::WrongType);
}
let mut val: Vec<u8> = vec![0; self.descriptor.size() as _]; let mut val: Vec<u8> = vec![0; self.descriptor.size() as _];
unsafe { unsafe {
checked(|| { checked(|| {
@ -331,7 +335,7 @@ impl Opt {
let list = unsafe { (*self.descriptor.0).constraint.word_list }; let list = unsafe { (*self.descriptor.0).constraint.word_list };
assert!(!list.is_null()); assert!(!list.is_null());
let len = unsafe { *list }; let len = unsafe { *list };
let list = unsafe { std::slice::from_raw_parts(list, len as _) }; let list = unsafe { std::slice::from_raw_parts(list, len as usize + 1) };
Ok(&list[1..]) Ok(&list[1..])
} }
fn get_int(&self) -> Result<SANE_Int, Error> { fn get_int(&self) -> Result<SANE_Int, Error> {
@ -502,9 +506,17 @@ impl Image {
} }
} }
const TESTDEVICE: bool = false; #[derive(Debug, Options)]
struct CliOptions {
#[options(help = "Use a destdevice")]
testdevice: bool,
#[options(help = "Directory to store images")]
dir: Option<String>,
}
fn main() { fn main() {
let cliopts = CliOptions::parse_args_default_or_exit();
let (context, version) = Context::init().unwrap(); let (context, version) = Context::init().unwrap();
println!( println!(
"Version: major: {} minor: {} build: {}", "Version: major: {} minor: {} build: {}",
@ -512,7 +524,7 @@ fn main() {
version.minor(), version.minor(),
version.build() version.build()
); );
let handle = if TESTDEVICE { let handle = if cliopts.testdevice {
Handle::from_name("test").unwrap() Handle::from_name("test").unwrap()
} else { } else {
let mut chosen_device = None; let mut chosen_device = None;
@ -542,6 +554,9 @@ fn main() {
} }
match optname { match optname {
"mode" => { "mode" => {
if !cliopts.testdevice {
option.set_string("Color").unwrap()
}
let active_mode = option.get_string().unwrap(); let active_mode = option.get_string().unwrap();
print!("\t\t"); print!("\t\t");
for opt in option.string_constraints().unwrap() { for opt in option.string_constraints().unwrap() {
@ -552,15 +567,14 @@ fn main() {
} }
} }
println!(); println!();
option.set_string("Color").unwrap(); option.set_string("color").unwrap()
} }
"depth" => { "depth" => {
println!("\t\tCurrent depth: {}", option.get_int().unwrap()); println!("\t\tCurrent depth: {}", option.get_int().unwrap());
} }
"resolution" => { "resolution" => {
let active_resolution = option.get_int().unwrap();
let mut max_resolution;
if let Ok(range) = option.get_range() { if let Ok(range) = option.get_range() {
let active_resolution = option.get_int().unwrap();
println!( println!(
"\t\tmin:{} max:{} quant:{} :: current: {}", "\t\tmin:{} max:{} quant:{} :: current: {}",
range.min(), range.min(),
@ -568,8 +582,9 @@ fn main() {
range.quant(), range.quant(),
active_resolution active_resolution
); );
max_resolution = range.max();
} else { } else {
option.set_int(&mut 300).unwrap();
let active_resolution = option.get_int().unwrap();
let resolutions = option.int_constraints().unwrap(); let resolutions = option.int_constraints().unwrap();
print!("\t\t"); print!("\t\t");
for &res in resolutions { for &res in resolutions {
@ -580,9 +595,7 @@ fn main() {
} }
} }
println!(); println!();
max_resolution = *resolutions.iter().max().unwrap();
} }
option.set_int(&mut max_resolution).unwrap();
} }
"test-picture" => { "test-picture" => {
option.set_string("Color pattern"); option.set_string("Color pattern");
@ -591,8 +604,29 @@ fn main() {
} }
} }
if let Some(dir) = cliopts.dir.as_ref() {
let dir = std::path::Path::new(dir);
std::fs::create_dir_all(&dir).unwrap();
loop {
// Check button
let acq = handle.start().unwrap(); let acq = handle.start().unwrap();
let image = acq.get_image().unwrap(); let image = acq.get_image().unwrap();
let now = std::time::SystemTime::now();
let since_unix = now.duration_since(std::time::UNIX_EPOCH).unwrap();
let mut imagepath = dir.join(format!(
"plate_{}:{}.png",
since_unix.as_secs(),
since_unix.subsec_millis()
));
assert!(!imagepath.exists());
image.save(imagepath).unwrap();
}
} else {
let acq = handle.start().unwrap();
let image = acq.get_image().unwrap();
image.save("test.png").unwrap(); image.save("test.png").unwrap();
}
} }