wallpaper 3.2.0

Gets and sets the desktop wallpaper/background.
Documentation
use crate::{get_stdout, run, Mode, Result};
use std::error::Error;

#[derive(Debug)]
struct NoDesktopsError;

impl Error for NoDesktopsError {}

impl std::fmt::Display for NoDesktopsError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "no desktops found")
    }
}

fn get_desktop_props(key: &str) -> Result<Vec<String>> {
    let stdout = get_stdout("xfconf-query", &["--channel", "xfce4-desktop", "--list"])?;
    let desktops = stdout
        .split('\n')
        .filter(|line| line.ends_with(key))
        .map(|desktop| desktop.to_string())
        .collect::<Vec<String>>();

    if desktops.is_empty() {
        return Err(Box::new(NoDesktopsError));
    }

    Ok(desktops)
}

pub fn get() -> Result<String> {
    let desktops = get_desktop_props("last-image")?;
    let path = get_stdout(
        "xfconf-query",
        &["--channel", "xfce4-desktop", "--property", &desktops[0]],
    )?;

    Ok(path.trim().to_string())
}

pub fn set(path: &str) -> Result<()> {
    for desktop in get_desktop_props("last-image")? {
        run(
            "xfconf-query",
            &[
                "--channel",
                "xfce4-desktop",
                "--property",
                &desktop,
                "--set",
                path,
            ],
        )?;
    }

    Ok(())
}

pub fn set_mode(mode: Mode) -> Result<()> {
    for property in get_desktop_props("image-style")? {
        run(
            "xfconf-query",
            &[
                "--channel",
                "xfce4-desktop",
                "--property",
                &property,
                "--set",
                match mode {
                    Mode::Center => "1",
                    Mode::Crop => "5",
                    Mode::Fit => "4",
                    Mode::Span => "5",
                    Mode::Stretch => "3",
                    Mode::Tile => "2",
                },
            ],
        )?;
    }

    Ok(())
}