rstango 0.4.0

Implementation of the Tango distributed control system
Documentation
//! How a failure comes back to a client, against a device of the `server` example:
//! an error has a kind to match on, a reason that is the Tango one, and a description for
//! a human.
//!
//! ```sh
//! cargo run --example errors -- test/motor/1
//! ```

use std::env;
use std::time::Duration;

use tango::dev::DevProxy;
use tango::error::{ErrorKind, Result};


/// Print what a request failed with, or that it did not, the alternate form giving the
/// whole chain of the error for a person to read.
fn report<T>(what: &str, res: Result<T>) {
    match res {
        Ok(_) => println!("{what}: no error"),
        Err(err) => println!("{what}: {err:#}"),
    }
}


fn main() -> Result<()> {

    let name = env::args().nth(1).unwrap_or_else(|| "test/motor/1".to_string());
    let motor = DevProxy::new(name.as_str());

    // The device refusing a request, with the reason and the description it gave.
    report("MoveTo past the limit", motor.command::<_, f64>("MoveTo", 1000.0));
    report("Writing past the limit", motor.write_attr(("position", 1000.0)));

    // A kind is what a client matches on to react to one failure and not the others.
    match motor.command::<_, ()>("Home", ()) {
        Err(err) if err.kind() == ErrorKind::CommandNotFound => println!("The motor has no Home command, as expected"),
        res => report("Unknown command", res),
    }

    // The interface of the device checked by the server.
    report("Argument of the wrong type", motor.command::<_, f64>("MoveTo", "north"));
    report("Writing a read-only attribute", motor.write_attr(("limit", 10.0)));
    report("Reading an unknown attribute", motor.read_attr::<f64, _>("velocity"));

    // A value of another type than the one asked for is caught by the client.
    report("Reading as the wrong type", motor.read_attr::<String, _>("position"));

    // No device of that name: the database says so, without waiting for any timeout.
    let mut missing = DevProxy::new("test/motor/missing");
    missing.set_timeout(Duration::from_secs(1));
    report("Unknown device", missing.ping());

    Ok(())

}