flameshot/
flameshot.rs

1#[cfg(feature = "image")]
2use image::{io::Reader as ImageReader, DynamicImage};
3#[cfg(feature = "image")]
4use std::io::Cursor;
5
6use std::process::Command;
7use std::process::Output;
8use std::str::from_utf8;
9
10pub use crate::flameshot_error::FlameshotError;
11pub use crate::params::FullArgs;
12pub use crate::params::GuiArgs;
13pub use crate::params::ScreenArgs;
14pub mod flameshot_error;
15pub mod params;
16
17/// Implements Cli parameters for flameshot.
18pub trait CmdParameters {
19    fn generate_args(&self) -> Vec<String>;
20}
21
22/// Gets returned from flameshot::execute(params)
23#[derive(Clone, Debug, Eq, PartialEq)]
24pub struct FlameshotOutput {
25    pub output: Output,
26    raw_enabled: bool,
27}
28
29/// Checks if flameshot stderr has produced an error
30fn has_error(stderr: &str) -> bool {
31    stderr.contains("error")
32}
33
34#[cfg(feature = "image")]
35impl FlameshotOutput {
36    /// Consumes self and returns a DynamicImage from the flameshot stdout, requires .raw() in params
37    pub fn to_dynamic_image(self) -> Result<DynamicImage, FlameshotError> {
38        if !self.raw_enabled {
39            return Err(FlameshotError::Image(
40                "You forgot to add .raw() to the param builder! which is a requirement for converting to a dynamic_image.".to_string(),
41            ));
42        }
43
44        let buffer = Cursor::new(self.output.stdout);
45        let reader = ImageReader::new(buffer).with_guessed_format();
46
47        let img = match reader {
48            Err(e) => return Err(FlameshotError::Image(e.to_string())),
49            Ok(img) => img,
50        };
51
52        match img.decode() {
53            Err(e) => Err(FlameshotError::Image(e.to_string())),
54            Ok(img) => Ok(img),
55        }
56    }
57}
58
59/// Executes a flameshot cli command with the specified params
60pub fn execute(params: impl CmdParameters) -> Result<FlameshotOutput, FlameshotError> {
61    let args = params.generate_args();
62    let raw_enabled = args.contains(&String::from("--raw"));
63    let output = Command::new("flameshot")
64        .args(args)
65        .output()
66        .map_err(|e| FlameshotError::Os(e.to_string()))?;
67
68    let stderr = from_utf8(&output.stderr).unwrap_or("").to_string();
69
70    match has_error(&stderr) {
71        true => Err(FlameshotError::Os(stderr)),
72        false => Ok(FlameshotOutput {
73            output,
74            raw_enabled,
75        }),
76    }
77}