nimbus/stateful/client/
fs_client.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! A SettingsClient that uses the file-system. Used for developer ergonomics
6//! (eg, for testing against experiments which are not deployed anywhere) and
7//! for tests.
8
9use crate::error::{info, warn, Result};
10use crate::stateful::client::SettingsClient;
11use crate::Experiment;
12use std::ffi::OsStr;
13use std::fs::File;
14use std::io::BufReader;
15use std::path::{Path, PathBuf};
16
17pub struct FileSystemClient {
18    path: PathBuf,
19}
20
21impl FileSystemClient {
22    pub fn new<P: AsRef<Path>>(path: P) -> Result<Self> {
23        Ok(Self {
24            path: path.as_ref().into(),
25        })
26    }
27}
28
29impl SettingsClient for FileSystemClient {
30    fn get_experiments_metadata(&self) -> Result<String> {
31        unimplemented!();
32    }
33
34    fn fetch_experiments(&self) -> Result<Vec<Experiment>> {
35        info!("reading experiments in {}", self.path.display());
36        let mut res = Vec::new();
37        // Skip directories and non .json files (eg, READMEs)
38        let json_ext = Some(OsStr::new("json"));
39        let filenames = self
40            .path
41            .read_dir()?
42            .filter_map(Result::ok)
43            .map(|c| c.path())
44            .filter(|f| f.is_file() && f.extension() == json_ext);
45        for child_path in filenames {
46            let file = File::open(child_path.clone())?;
47            let reader = BufReader::new(file);
48            match serde_json::from_reader::<_, Experiment>(reader) {
49                Ok(exp) => res.push(exp),
50                Err(e) => {
51                    warn!(
52                        "Malformed experiment found! File {},  Error: {}",
53                        child_path.display(),
54                        e
55                    );
56                }
57            }
58        }
59        Ok(res)
60    }
61}