blob: 9f4d6ff3a38c623069a72ea3d32d3b9a90bc70c9 [file] [log] [blame]
// Copyright 2020 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 {
crate::config::api::{ConfigLevel, ReadConfig, WriteConfig},
crate::config::persistent_config::Persistent,
anyhow::{anyhow, Error},
serde_json::Value,
std::fs::{File, OpenOptions},
std::io::{BufReader, BufWriter},
};
pub struct FileBacked {
data: Persistent,
}
impl FileBacked {
fn reader_from_ref(path: &Option<&String>) -> Result<Option<BufReader<File>>, Error> {
match path {
Some(p) => match File::open(p) {
Ok(f) => Ok(Some(BufReader::new(f))),
Err(e) => Err(anyhow!("Could not open file {}", e)),
},
None => Ok(None),
}
}
fn reader(path: &Option<String>) -> Result<Option<BufReader<File>>, Error> {
match path {
Some(p) => match File::open(p) {
Ok(f) => Ok(Some(BufReader::new(f))),
Err(e) => Err(anyhow!("Could not open file {}", e)),
},
None => Ok(None),
}
}
fn writer_from_ref(path: &Option<&String>) -> Result<Option<BufWriter<File>>, Error> {
match path {
Some(p) => {
let file = OpenOptions::new().write(true).truncate(true).create(true).open(p);
match file {
Ok(f) => Ok(Some(BufWriter::new(f))),
Err(e) => Err(anyhow!("Could not open file {}", e)),
}
}
None => Ok(None),
}
}
fn writer(path: &Option<String>) -> Result<Option<BufWriter<File>>, Error> {
match path {
Some(p) => {
let file = OpenOptions::new().write(true).truncate(true).create(true).open(p);
match file {
Ok(f) => Ok(Some(BufWriter::new(f))),
Err(e) => Err(anyhow!("Could not open file {}", e)),
}
}
None => Ok(None),
}
}
pub(crate) fn load(
global: &Option<String>,
build: &Option<&String>,
user: &Option<String>,
) -> Result<Self, Error> {
let data = Persistent::load(
FileBacked::reader(global)?,
FileBacked::reader_from_ref(build)?,
FileBacked::reader(user)?,
)?;
Ok(Self { data })
}
pub(crate) fn save(
&self,
global: &Option<String>,
build: &Option<&String>,
user: &Option<String>,
) -> Result<(), Error> {
self.data.save(
FileBacked::writer(global)?,
FileBacked::writer_from_ref(build)?,
FileBacked::writer(user)?,
)
}
}
impl ReadConfig for FileBacked {
fn get(&self, key: &str) -> Option<Value> {
self.data.get(key)
}
}
impl WriteConfig for FileBacked {
fn set(&mut self, level: &ConfigLevel, key: &str, value: Value) -> Result<(), Error> {
self.data.set(level, key, value)
}
fn remove(&mut self, level: &ConfigLevel, key: &str) -> Result<(), Error> {
self.data.remove(level, key)
}
}