Crate cvar [−] [src]
Let us use an example to see how cvars might be implemented for it.
extern crate cvar; use ::std::cell::{Cell, RefCell}; struct Foo { int: Cell<i32>, name: RefCell<String>, } impl Foo { fn greet(&self, ctx: &mut cvar::Context) -> cvar::BoxResult<()> { Ok(try!(writeln!(ctx.write, "Hello, {}!", *self.name.borrow()))) } }
Important is that this library is designed with passing non-mutable references around, thus configurable variables need interior mutability.
That is the basic setup, we would like to create these properties:
foo.int
: Property representing ani32
variable.foo.name
: The name used in the greeting.foo.greet!
: An action that will print a greeting forfoo.name
. See theOnInvoke
trait for more information about its parameters.
impl cvar::IVisit for Foo { fn visit(&self, f: &mut FnMut(cvar::Node)) { use cvar::{Property, Action}; f(From::from(&Property::new("int", "int description", &self.int, 42))); f(From::from(&Property::new("name", "name description", &self.name, "Casper"))); f(From::from(&Action::new("greet!", "action description", |ctx| self.greet(ctx)))); } }
Accessing children is done via the IVisit
trait implementing the Visitor Pattern. Its implementation will invoke the callback with every child as a Node
.
struct Root { foo: Foo, } impl cvar::IVisit for Root { fn visit(&self, f: &mut FnMut(cvar::Node)) { use cvar::List; f(From::from(&List::new("foo", "foo description", &self.foo))); } }
To access these cvars there is one thing missing: a root object from which they are reachable. Here modeled by having the root own a Foo
instance.
An important note is that the root is not a list node, it does not have any metadata it just exists as a point where the rest of the cvars are accessible from.
let root = Root { foo: Foo { int: Cell::new(13), name: RefCell::new(String::new()), }, };
That's it! Now we are almost ready, let us create an instance of the root.
assert_eq!(cvar::console::get(&root, "foo.int").unwrap(), "13"); cvar::console::set(&root, "foo.int", "7").unwrap(); assert_eq!(root.foo.int.get(), 7); cvar::console::reset(&root, "foo.name").unwrap(); assert_eq!(*root.foo.name.borrow(), "Casper"); let mut console = Vec::new(); cvar::console::invoke(&root, "foo.greet!", &mut cvar::Context::new("-o arg", &mut console)).unwrap(); assert_eq!(console, b"Hello, Casper!\n");
And use various console functions to interact with the resulting configuration.
See examples/repl.rs
for a more complex example!
Modules
console |
Interact with the cvar hierarchy. |
Structs
Action |
Action instance. |
Context |
Invocation context. |
Error |
Contextual error. |
List |
List instance. |
Pass |
Pass through dummy. |
Property |
Property instance. |
Enums
InnerError |
Contextless error. |
Node |
Node interface. |
PropState |
Property state. |
Constants
JOINER |
Identifiers are node names joined with a separator. |
Traits
AutoValue |
Implement |
IAction |
Action node interface. |
IList |
List node interface. |
INode |
Node interface. |
IProperty |
Property node interface. |
IVisit |
Visitor Pattern interface. |
OnChange |
Property callback when its value is changed. |
OnInvoke |
Action callback when invoked. |
Value |
Accepted property value types. |
Variable |
Abstraction over interior mutability. |
Type Definitions
BoxResult |
Result with boxed error. |