Skip to content

Instantly share code, notes, and snippets.

@cholcombe973
Created January 9, 2017 19:24
Show Gist options
  • Save cholcombe973/b39c74e5bfc4f6ddaa1ffe3e8be730b4 to your computer and use it in GitHub Desktop.
Save cholcombe973/b39c74e5bfc4f6ddaa1ffe3e8be730b4 to your computer and use it in GitHub Desktop.
/// A HashMap representation of the charm's config.yaml, with some
/// extra features:
/// - See which values in the HashMap have changed since the previous hook.
/// - For values that have changed, see what the previous value was.
/// - Store arbitrary data for use in a later hook.
#[derive(Debug)]
pub struct Config {
values: HashMap<String, String>,
}
impl Config {
/// Create a new Config and automatically load the previous config values if the
/// .juju-persistent-config is present
/// The .juju-persistent-config is also saved automatically when this struct is dropped.
pub fn new() -> Result<Self, JujuError> {
if Path::new(".juju-persistent-config").exists() {
// Load the values from disk
let mut file = try!(OpenOptions::new()
.read(true)
.open(".juju-persistent-config"));
let mut s = String::new();
try!(file.read_to_string(&mut s));
let previous_values: HashMap<String, String> = try!(serde_json::from_str(&s));
Ok(Config { values: previous_values })
} else {
// Initalize with a blank values map
Ok(Config { values: HashMap::new() })
}
}
/// Return True if the current value for this key is different from
/// the previous value.
pub fn changed(self, key: &str) -> Result<bool, JujuError> {
match self.values.get(key) {
Some(previous_value) => {
let current_value = try!(config_get(key));
Ok(&current_value != previous_value)
}
// No previous key
None => Ok(true),
}
}
/// Return previous value for this key, or None if there
/// is no previous value.
pub fn previous(self, key: &str) -> Option<String> {
match self.values.get(key) {
Some(previous_value) => Some(previous_value.clone()),
None => None,
}
}
}
impl Drop for Config {
// Automatic saving of the .juju-persistent-config file when this struct is dropped
fn drop(&mut self) {
let mut file =
match OpenOptions::new().write(true).truncate(true).open(".juju-persistent-config") {
Ok(f) => f,
Err(e) => {
log(&format!("Unable to open .juju-persistent-config file for writing. Err: \
{}",
e),
Some(LogLevel::Error));
return;
}
};
let serialized = match serde_json::to_string(&self.values) {
Ok(f) => f,
Err(e) => {
log(&format!("Unable to serialize Config values: {:?}. Err: {}",
&self.values,
e),
Some(LogLevel::Error));
return;
}
};
match file.write(&serialized.as_bytes()) {
Ok(bytes_written) => {
log(&format!(".juju-persistent-config saved. Wrote {} bytes",
bytes_written),
Some(LogLevel::Debug));
}
Err(e) => {
log(&format!("Unable to write to .juju-persistent-config Err: {}", e),
Some(LogLevel::Error));
return;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment