Trait InteractiveRoot

Source
pub trait InteractiveRoot: Interactive + Sized {
    // Provided methods
    fn eval_to_string(&mut self, query: &str) -> String { ... }
    fn eval_and_write<T>(&mut self, query: &str, buf: &mut T) -> Result
       where T: Write { ... }
    fn try_eval<F>(&self, query: &str, f: F)
       where F: FnMut(Result<'_, &dyn Debug>) { ... }
    fn try_eval_mut<F>(&mut self, query: &str, f: F)
       where F: FnMut(Result<'_, &dyn Debug>) { ... }
    fn get_queried_object<'a>(
        &'a self,
        query: &'a str,
    ) -> Result<'_, (&dyn Interactive, &str)> { ... }
    fn get_queried_object_mut<'a>(
        &'a mut self,
        query: &'a str,
    ) -> Result<'_, (&mut dyn Interactive, &str)> { ... }
}
Expand description

The main entry point to everything interactive.

The provided methods are not meant to be overridden. This trait gets implemented automatically when you derive it with InteractiveRoot.

It provides access to interactive fields, methods, and free functions by means of a string query.

A query looks just like normal Rust syntax. Possible queries are:

  • free_function()
  • field_of_root
  • field_of_root.child_field
  • field_of_root.child_method()
  • etc.

Functions can be called with arguments just as you would in Rust:

  • takes_bool(true)
  • takes_nums(1, 2)
  • takes_char('C')
  • takes_string_like("foo")

Chars and string like types support escaping:

  • show_escaping('\x41', "\u{1f980} is \u{2764}")

Currently supported argument types are:

bool, char, f32, f64, i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, String, str

References to these types are also supported.

Generic argument types are not supported.

Both String and str are only available with default features on.

Provided Methods§

Source

fn eval_to_string(&mut self, query: &str) -> String

Evaluates the query and returns the result as a String. Not available in no_std contexts.

Source

fn eval_and_write<T>(&mut self, query: &str, buf: &mut T) -> Result
where T: Write,

Evaluates the query and writes the result into the provided buffer. Useful in no_std contexts.

Source

fn try_eval<F>(&self, query: &str, f: F)
where F: FnMut(Result<'_, &dyn Debug>),

Evaluates the given query and calls the given closure with a Result<&dyn Debug>.

This method does not have access to methods that take &mut self as their receiver, use try_eval_mut instead.

§Example
#[derive(Interactive, Debug, Default)]
struct Child {
    field1: bool
}
#[Methods]
impl Child {
    fn add(&self, a: u8, b: u8) -> u8 {
        a + b
    }
    fn toggle(&mut self){
        self.field1 = !self.field1;
    }
}

#[derive(InteractiveRoot, Debug, Default)]
struct Root {
    child: Child,
}

let mut root = Root::default();
root.try_eval("child.add(1, 2)", |result| assert_eq!(format!("{:?}", result.unwrap()), "3"));
root.try_eval("child.field1", |result| assert_eq!(format!("{:?}", result.unwrap()), "false"));
root.try_eval("child.toggle()", |result| assert_eq!(format!("{}", result.unwrap_err()), "No method named `toggle` found for type `Child`"));
Source

fn try_eval_mut<F>(&mut self, query: &str, f: F)
where F: FnMut(Result<'_, &dyn Debug>),

Evaluates the given query and calls the given closure with a Result<&dyn Debug>.

If mutability is required access will only succeed for owned fields or fields behind a &mut.

§Example
#[derive(Interactive, Debug, Default)]
struct Child {
    field1: bool
}
#[Methods]
impl Child {
    fn toggle(&mut self){
        self.field1 = !self.field1;
    }
}

#[derive(InteractiveRoot, Debug)]
struct Root<'a> {
    owned: Child,
    borrowed: &'a Child,
}

let mut root = Root{ owned: Child::default(), borrowed: &Child::default()};
root.try_eval_mut("owned.toggle()", |result| assert!(result.is_ok()));
root.try_eval_mut("owned.field1", |result| assert_eq!(format!("{:?}", result.unwrap()), "true"));
root.try_eval_mut("borrowed.toggle()", |result| assert!(result.is_err()));
root.try_eval_mut("borrowed.field1", |result| assert_eq!(format!("{:?}", result.unwrap()), "false"));
Source

fn get_queried_object<'a>( &'a self, query: &'a str, ) -> Result<'_, (&dyn Interactive, &str)>

Splits the given query into an object path and a rest expression.

Then recursively looks for an object matching the given object path and if successful returns a shared reference to it together with the rest expression.

The object path is the part of the given query before the last .

E.g. "path.to.obj.foo" will split into the object path "path.to.obj" and the rest expression "foo".

§Example
#[derive(Interactive, Debug, Default)]
struct Child {
    field1: bool
}

#[derive(InteractiveRoot, Debug, Default)]
struct Root {
    child: Child,
}

let root = Root::default();
let (child, rest_expression) = root.get_queried_object("child.rest").unwrap();
assert_eq!(child.get_all_field_names(), &["field1"]);
assert_eq!(rest_expression, "rest");
Source

fn get_queried_object_mut<'a>( &'a mut self, query: &'a str, ) -> Result<'_, (&mut dyn Interactive, &str)>

Same as get_queried_object but returning a mutable reference.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§