configlib 0.1.2

A crate for handling application-agnostic config files
Documentation
use std::fs::{self, File};
#[cfg(test)]
mod tests {
    use crate::create_new_config;

    #[test]
    fn set_val() {
        let config = create_new_config("test.conf").unwrap();
        config.set_val("a", "b").unwrap();
        config.set_val("c", "d").unwrap();
        assert_eq!(config.get_val("a").unwrap(), "b");
        assert_eq!(config.get_val("c").unwrap(), "d");
    }
}
#[derive(Clone)]
pub struct Config {
    path: String,
}
/// Create a new config file and return it.
pub fn create_new_config<T: Into<String> + Copy>(path: T) -> Result<Config, std::io::Error> {
    File::create(path.into())?;
    Ok(Config { path: path.into() })
}
/// Returns a config object from the file path provided.
pub fn get_config<T: Into<String> + Copy>(path: T) -> Config {
    Config { path: path.into() }
}
impl Config {
    /// Creates a new Config object - equivalent to get_config()
    pub fn new<T: Into<String>>(path: T) -> Config {
        Config { path: path.into() }
    }
    // Sets a value in the configuration file or creates it if it does not exist.
    pub fn set_val<
        T: Into<String> + Clone + std::convert::AsRef<std::path::Path> + std::fmt::Display + Copy,
    >(
        &self,
        key: T,
        value: T,
    ) -> Result<(), std::io::Error> {
        let db_path = &self.path;
        let db_contents = return_config_file_as_string(db_path)?;
        let mut pairs: Vec<String> = db_contents.split("\n").map(|v| v.to_owned()).collect();
        let mut index = 0;
        while index < pairs.len() {
            let pair: Vec<String> = pairs[index]
                .clone()
                .split("=")
                .map(|v| v.to_string())
                .collect();
            if pair.get(0) == Some(&key.clone().into()) {
                pairs[index] = format!("{}={}", key, value);
            }
            index += 1;
        }

        if !pairs.contains(&format!("{}={}", key, value)) {
            pairs.push(format!("{}={}", key, value));
        }
        let mut final_string = String::new();
        for item in pairs {
            final_string += &(item + "\n");
        }
        fs::write(db_path, final_string)
    }
    /// Get a value from the config
    pub fn get_val<
        T: Into<String> + Clone + std::convert::AsRef<std::path::Path> + std::fmt::Display + Copy,
    >(
        &self,
        key: T,
    ) -> Option<String> {
        let contents = return_config_file_as_string(&self.path);
        let binding = contents.ok()?;
        let splits: Vec<&str> = binding.split("\n").collect();
        for pair in splits {
            if pair.split("=").nth(0) == Some(&key.into()) {
                let x = &pair.split("=").collect::<Vec<&str>>()[1];
                return Some(x.to_string());
            }
        }
        None
    }
}
fn return_config_file_as_string<T: Into<String> + std::convert::AsRef<std::path::Path>>(
    path: T,
) -> Result<String, std::io::Error> {
    fs::read_to_string(path)
}