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§
Sourcefn eval_to_string(&mut self, query: &str) -> String
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.
Sourcefn eval_and_write<T>(&mut self, query: &str, buf: &mut T) -> Resultwhere
T: Write,
fn eval_and_write<T>(&mut self, query: &str, buf: &mut T) -> Resultwhere
T: Write,
Evaluates the query and writes the result into the provided buffer. Useful in no_std contexts.
Sourcefn try_eval<F>(&self, query: &str, f: F)
fn try_eval<F>(&self, query: &str, f: F)
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`"));
Sourcefn try_eval_mut<F>(&mut self, query: &str, f: F)
fn try_eval_mut<F>(&mut self, query: &str, f: F)
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"));
Sourcefn get_queried_object<'a>(
&'a self,
query: &'a str,
) -> Result<'_, (&dyn Interactive, &str)>
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");
Sourcefn get_queried_object_mut<'a>(
&'a mut self,
query: &'a str,
) -> Result<'_, (&mut dyn Interactive, &str)>
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.