pub trait DynamicVariable {
// Required methods
fn get(&mut self) -> Option<CString>;
fn set(&mut self, value: &CStr);
}
Expand description
The DynamicVariable
provides the implementation to create dynamic
variables.
get
is called when the value of the shell variable is required. set
is called when a value is assigned to a variable.
Use variables::bind
to create a dynamic variable with an instance of a
type implementing DynamicVariable
.
§Deleting Dynamic Variables
A dynamic variable can be deleted with unset
. However, the instance
bound to it is not dropped, since bash does not notify when a variable is
removed.
If the builtin is removed (enable -d <name>
), dynamic variables are
removed before unloading the shared object.
§Example
To create a counter using DynamicVariable
, first we need to implement a
Counter
type similar to this:
use std::ffi::{CStr, CString};
use bash_builtins::error;
use bash_builtins::variables::DynamicVariable;
struct Counter(isize);
impl DynamicVariable for Counter {
fn get(&mut self) -> Option<CString> {
let value = CString::new(format!("{}", self.0)).ok();
self.0 += 1;
value
}
fn set(&mut self, value: &CStr) {
self.0 = match value.to_str().map(str::parse) {
Ok(Ok(n)) => n,
_ => {
error!("invalid value: {:?}", value);
return;
}
}
}
}
Then, dynamic variables with any name can be created using a function like this:
use bash_builtins::variables::{bind, VariableError};
fn create_counter(name: &str) -> Result<(), VariableError> {
bind(name, Counter(0))
}
The varcounter
example implements this functionality:
$ cargo build --release --examples
$ enable -f target/release/examples/libvarcounter.so varcounter
$ varcounter FOO BAR
$ echo $FOO
0
$ echo $FOO
1
$ echo $FOO
2
$ echo $FOO $BAR $BAR
3 0 1
$ FOO=1000
$ echo $FOO
1000
$ echo $FOO
1001