Browse Source

Moved config into a module

develop
Drew Short 6 years ago
parent
commit
97e273cb72
  1. 174
      src/config.rs
  2. 50
      src/config/default.rs
  3. 30
      src/config/error.rs
  4. 32
      src/config/load.rs
  5. 4
      src/config/mod.rs
  6. 66
      src/config/model.rs
  7. 2
      src/main.rs

174
src/config.rs

@ -1,174 +0,0 @@
use serde_yaml;
use std::error::Error;
use std::fmt;
use std::fs::File;
use std::io::prelude::*;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct ServerConfig {
pub host: Option<String>,
pub port: Option<i32>,
pub workers: Option<usize>
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct CloudflareDomainConfig {
pub domain: String,
pub zone_id: String
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct CloudflareConfig {
pub domains: Vec<CloudflareDomainConfig>,
pub key: String,
pub email: String
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct DDNSDomain {
pub domain: String,
pub subdomains: Vec<String>
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct DDNSConfig {
pub domains: Vec<DDNSDomain>
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct UserSubdomainConfig {
subdomain: String,
targets: Vec<String>
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct UserDomainConfig {
pub domain: String,
pub subdomains: Vec<UserSubdomainConfig>
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct UserConfig {
pub username: String,
pub token: String,
pub domains: Vec<UserDomainConfig>
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Config {
pub server: ServerConfig,
pub cloudflare: CloudflareConfig,
pub ddns: DDNSConfig,
pub users: Vec<UserConfig>
}
fn get_default_config() -> Config {
Config {
server: ServerConfig {
host: Option::Some(String::from("localhost")),
port: Option::Some(8080),
workers: Option::Some(4)
},
cloudflare: CloudflareConfig {
email: String::from("something@something.com"),
key: String::from("IAmNotAKey"),
domains: vec![
CloudflareDomainConfig {
domain: String::from("IAmNotADomain.com"),
zone_id: String::from("IAmNotAZoneID")
}
]
},
ddns: DDNSConfig {
domains: vec![
DDNSDomain {
domain: String::from("IAmNotADomain.com"),
subdomains: vec![
String::from("ddns")
]
}
]
},
users: vec![
UserConfig {
username: String::from("userOne"),
token: String::from("6d37d7a9-6b6b-4db2-99f2-c261e4f4b922"),
domains: vec![
UserDomainConfig {
domain: String::from("IAmNotADomain.com"),
subdomains: vec![
UserSubdomainConfig {
subdomain: String::from("ddns"),
targets: vec![
String::from("home")
]
}
]
}
]
}
]
}
}
#[derive(Debug)]
pub struct ConfigError {
description: String,
original_error: Option<Box<Error>>
}
impl ConfigError {
fn new(description: &str, original_error: Option<Box<Error>>) -> ConfigError {
ConfigError {
description: String::from(description),
original_error
}
}
}
impl Error for ConfigError {}
impl fmt::Display for ConfigError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.original_error {
Some(original_error) => {
write!(f, "{}: \"{}\"", self.description, original_error)
},
None => write!(f, "{}", self.description)
}
}
}
fn read_config(yaml_str: &str) -> Result<Config, ConfigError> {
match serde_yaml::from_str(yaml_str) {
Ok(v) => Result::Ok(v),
Err(e) => Result::Err(ConfigError::new("Invalid Configuration", Option::Some(Box::from(e))))
}
}
pub fn load_config(path: &str) -> Result<Config, ConfigError> {
match File::open(path) {
Ok(mut file) => {
let mut contents = String::new();
match file.read_to_string(&mut contents) {
Ok(c) => {
if c > 0 {
read_config(&contents)
} else {
Result::Err(ConfigError::new("Empty Configuration File", Option::None))
}
},
Err(e) => Result::Err(ConfigError::new("Cannot Read Configuration File", Option::Some(Box::from(e))))
}
},
Err(_e) => Result::Err(ConfigError::new(&format!("Configuration File Doesn't Exist \"{}\"", path), Option::None))
}
}

50
src/config/default.rs

@ -0,0 +1,50 @@
use config::model::*;
fn get_default_config() -> Config {
Config {
server: ServerConfig {
host: Option::Some(String::from("localhost")),
port: Option::Some(8080),
workers: Option::Some(4)
},
cloudflare: CloudflareConfig {
email: String::from("something@something.com"),
key: String::from("IAmNotAKey"),
domains: vec![
CloudflareDomainConfig {
domain: String::from("IAmNotADomain.com"),
zone_id: String::from("IAmNotAZoneID")
}
]
},
ddns: DDNSConfig {
domains: vec![
DDNSDomain {
domain: String::from("IAmNotADomain.com"),
subdomains: vec![
String::from("ddns")
]
}
]
},
users: vec![
UserConfig {
username: String::from("userOne"),
token: String::from("6d37d7a9-6b6b-4db2-99f2-c261e4f4b922"),
domains: vec![
UserDomainConfig {
domain: String::from("IAmNotADomain.com"),
subdomains: vec![
UserSubdomainConfig {
subdomain: String::from("ddns"),
targets: vec![
String::from("home")
]
}
]
}
]
}
]
}
}

30
src/config/error.rs

@ -0,0 +1,30 @@
use std::error::Error;
use std::fmt;
#[derive(Debug)]
pub struct ConfigError {
description: String,
original_error: Option<Box<Error>>
}
impl ConfigError {
pub fn new(description: &str, original_error: Option<Box<Error>>) -> ConfigError {
ConfigError {
description: String::from(description),
original_error
}
}
}
impl Error for ConfigError {}
impl fmt::Display for ConfigError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.original_error {
Some(original_error) => {
write!(f, "{}: \"{}\"", self.description, original_error)
},
None => write!(f, "{}", self.description)
}
}
}

32
src/config/load.rs

@ -0,0 +1,32 @@
use serde_yaml;
use std::fs::File;
use std::io::prelude::*;
use config::error::ConfigError;
use config::model::Config;
fn read_config(yaml_str: &str) -> Result<Config, ConfigError> {
match serde_yaml::from_str(yaml_str) {
Ok(v) => Result::Ok(v),
Err(e) => Result::Err(ConfigError::new("Invalid Configuration", Option::Some(Box::from(e))))
}
}
pub fn read(path: &str) -> Result<Config, ConfigError> {
match File::open(path) {
Ok(mut file) => {
let mut contents = String::new();
match file.read_to_string(&mut contents) {
Ok(c) => {
if c > 0 {
read_config(&contents)
} else {
Result::Err(ConfigError::new("Empty Configuration File", Option::None))
}
},
Err(e) => Result::Err(ConfigError::new("Cannot Read Configuration File", Option::Some(Box::from(e))))
}
},
Err(_e) => Result::Err(ConfigError::new(&format!("Configuration File Doesn't Exist \"{}\"", path), Option::None))
}
}

4
src/config/mod.rs

@ -0,0 +1,4 @@
pub mod default;
pub mod error;
pub mod load;
pub mod model;

66
src/config/model.rs

@ -0,0 +1,66 @@
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct ServerConfig {
pub host: Option<String>,
pub port: Option<i32>,
pub workers: Option<usize>
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct CloudflareDomainConfig {
pub domain: String,
pub zone_id: String
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct CloudflareConfig {
pub domains: Vec<CloudflareDomainConfig>,
pub key: String,
pub email: String
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct DDNSDomain {
pub domain: String,
pub subdomains: Vec<String>
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct DDNSConfig {
pub domains: Vec<DDNSDomain>
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct UserSubdomainConfig {
pub subdomain: String,
pub targets: Vec<String>
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct UserDomainConfig {
pub domain: String,
pub subdomains: Vec<UserSubdomainConfig>
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct UserConfig {
pub username: String,
pub token: String,
pub domains: Vec<UserDomainConfig>
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Config {
pub server: ServerConfig,
pub cloudflare: CloudflareConfig,
pub ddns: DDNSConfig,
pub users: Vec<UserConfig>
}

2
src/main.rs

@ -73,7 +73,7 @@ fn main() {
.get_matches();
let config_path: &str = args.value_of("config").unwrap_or("/etc/rsddns/rsddns.yml");
let config = match config::load_config(config_path) {
let config = match config::load::read(config_path) {
Ok(c) => {
info!("Loaded configuration from \"{}\"", config_path);
Option::Some(c)

Loading…
Cancel
Save