blob: 22ad9b4e5afb22f5cb477da2a187377a17a4daa3 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use serde::de::DeserializeOwned;
use std::fmt::Display;
use std::fs::File;
use std::io::BufReader;
use std::path::Path;
use crate::service::message::Messenger;
pub struct DefaultSetting<T, P>
where
T: DeserializeOwned + Clone,
P: AsRef<Path> + Display,
{
default_value: Option<T>,
config_file_path: P,
cached_value: Option<Option<T>>,
_messenger: Option<Messenger>,
// Whether to log the config loads into inspect.
_log_config_loads: bool,
}
impl<T, P> DefaultSetting<T, P>
where
T: DeserializeOwned + Clone,
P: AsRef<Path> + Display,
{
pub fn new(
default_value: Option<T>,
config_file_path: P,
messenger: Option<Messenger>,
log_config_loads: bool,
) -> Self {
DefaultSetting {
default_value,
config_file_path,
cached_value: None,
_messenger: messenger,
_log_config_loads: log_config_loads,
}
}
pub fn get_default_value(&mut self) -> Option<T> {
if self.cached_value.is_none() {
self.cached_value = Some(self.load_default_settings());
}
self.cached_value.as_ref().unwrap().clone()
}
/// Attempts to load the settings from the given config_file_path.
///
/// Returns the default value if unable to read or parse the file. The returned option will
/// only be None if the default_value was provided as None.
fn load_default_settings(&self) -> Option<T> {
File::open(self.config_file_path.as_ref())
.map_err(|_e| {
// TODO(fxbug.dev/67569): Report config load status.
})
.ok()
.and_then(|file| {
serde_json::from_reader(BufReader::new(file))
.map_err(|_e| {
// TODO(fxbug.dev/67569): Report config load status.
})
.ok()
})
.unwrap_or_else(|| self.default_value.clone())
}
}
#[cfg(test)]
pub mod testing {
use super::*;
use serde::Deserialize;
#[derive(Clone, Deserialize)]
struct TestConfigData {
value: u32,
}
#[test]
fn test_load_valid_config_data() {
let mut setting = DefaultSetting::new(
Some(TestConfigData { value: 3 }),
"/config/data/fake_config_data.json",
None,
true,
);
assert_eq!(setting.get_default_value().unwrap().value, 10);
}
#[test]
fn test_load_invalid_config_data() {
let mut setting = DefaultSetting::new(
Some(TestConfigData { value: 3 }),
"/config/data/fake_invalid_config_data.json",
None,
true,
);
assert_eq!(setting.get_default_value().unwrap().value, 3);
}
#[test]
fn test_load_invalid_config_file_path() {
let mut setting =
DefaultSetting::new(Some(TestConfigData { value: 3 }), "nuthatch", None, true);
assert_eq!(setting.get_default_value().unwrap().value, 3);
}
#[test]
fn test_load_default_none() {
let mut setting = DefaultSetting::<TestConfigData, &str>::new(None, "nuthatch", None, true);
assert!(setting.get_default_value().is_none());
}
}