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.
//! One question to the WaOS on this machine about a program it runs, for `cargo waos screenshot`,
//! `tap`, `type`, `key` and `scroll`: connected to as it runs, never started, since only a program
//! a run of `cargo waos run` runs is read or driven (the design's decision 60), the protocol
//! agreed, the question sent, and its one answer read.
//!
//! The invariant: nothing here starts WaOS. With none answering, there is no run to ask about.

use std::io::ErrorKind;

use anyhow::{Context, Result, bail};
use waos_dev_protocol::{Connection, FromWaOS, ToWaOS};

/// What the WaOS running answers `question`.
pub async fn ask(question: &ToWaOS) -> Result<FromWaOS> {
    let socket = waos_dev_protocol::socket_path();
    let mut connection = match Connection::connect(&socket).await {
        Ok(connection) => connection,
        Err(error)
            if matches!(
                error.kind(),
                ErrorKind::NotFound | ErrorKind::ConnectionRefused
            ) =>
        {
            bail!(
                "no WaOS answers at {}: run the program with `cargo waos run` first",
                socket.display()
            )
        }
        Err(error) => {
            return Err(error)
                .with_context(|| format!("connecting to WaOS at {}", socket.display()));
        }
    };
    connection
        .agree_on_protocol()
        .await
        .context("the WaOS that answered")?;
    connection.send(question).await.context("sending to WaOS")?;
    connection
        .receive::<FromWaOS>()
        .await
        .context("reading from WaOS")?
        .context("WaOS closed the connection without an answer")
}