waos-cli 0.2.0

cargo waos: writes a new program, builds a program as a component, runs it in the WaOS on this machine, packages it as a signed .wapk, and takes screenshots of its windows and gives them input while it runs.
//! What `cargo waos` says when a screenshot or an input reached no window of the program, and why.

use waos_dev_protocol::Unreached;
use waos_package::ProgramId;

/// What `unreached` means for the program `id`, whose window `window` the input was for, in the
/// words `cargo waos` prints.
pub fn said(unreached: &Unreached, id: &ProgramId, window: u32) -> String {
    match unreached {
        Unreached::NotRunByCargoWaos => format!(
            "{id} is not running from `cargo waos run`: run it with `cargo waos run` in another shell first; a program opened from WaOS's library is neither read nor driven"
        ),
        Unreached::NoWindow { windows: 0, .. } => {
            format!("{id} has no window open")
        }
        Unreached::NoWindow { window, windows } => {
            format!("{id} has no window {window}: it has {windows}, numbered from 1")
        }
        Unreached::OutsideWindow { width, height } => format!(
            "the point is outside window {window} of {id}, which is {width}x{height} pixels"
        ),
        Unreached::NotEditing => format!(
            "nothing in window {window} of {id} is being edited: tap a text field first, or send keys with `cargo waos key`"
        ),
        Unreached::UnknownKey(chord) => format!(
            "no key is named {chord:?}: name a letter, a digit, one of - = [ ] \\ ; ' ` , . /, or enter, escape, tab, space, backspace, delete, up, down, left, right, home, end, pageup, pagedown or f1 to f12, after any of cmd+, ctrl+, alt+ and shift+"
        ),
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    fn notes() -> ProgramId {
        "dev.example.notes".parse().unwrap()
    }

    #[test]
    fn each_refusal_says_what_to_do_next() {
        let said = |unreached| said(&unreached, &notes(), 2);
        assert!(said(Unreached::NotRunByCargoWaos).contains("cargo waos run"));
        assert_eq!(
            said(Unreached::NoWindow {
                window: 2,
                windows: 1
            }),
            "dev.example.notes has no window 2: it has 1, numbered from 1"
        );
        assert_eq!(
            said(Unreached::NoWindow {
                window: 1,
                windows: 0
            }),
            "dev.example.notes has no window open"
        );
        assert!(
            said(Unreached::OutsideWindow {
                width: 800,
                height: 600
            })
            .contains("window 2 of dev.example.notes, which is 800x600 pixels")
        );
        assert!(said(Unreached::NotEditing).contains("tap a text field first"));
        assert!(
            said(Unreached::UnknownKey("hyper+q".into()))
                .starts_with("no key is named \"hyper+q\"")
        );
    }
}