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 an i32 variable.

  • foo.name: The name used in the greeting.

  • foo.greet!: An action that will print a greeting for foo.name. See the OnInvoke 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 Value automatically for types that have appropriate FromStr and ToString implementations.

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.