config.rs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. extern crate serde;
  2. extern crate serde_yaml;
  3. use std::fs::{File};
  4. use std::path::Path;
  5. use std::io::prelude::*;
  6. use std::process::exit;
  7. use std::env;
  8. use self::serde::{Deserialize};
  9. mod config {}
  10. // TODO: built-in validator.
  11. // For now, ensure any built Config has called validate()
  12. #[derive(Debug, PartialEq, Deserialize)]
  13. pub struct Config {
  14. pub words: Vec<String>,
  15. pub choose: usize,
  16. pub rows: Option<usize>,
  17. pub cols: Option<usize>
  18. }
  19. pub fn default_config_file() -> String {
  20. let config_folders = [
  21. env::var("XDG_CONFIG_HOME"),
  22. env::var("HOME").and_then(|s| Ok(String::from(Path::new(&s).join(".config").to_str().unwrap()))),
  23. Ok(String::from("./"))
  24. ];
  25. for f in config_folders.iter() {
  26. match f {
  27. Err(_) => continue,
  28. Ok(dir) => {
  29. let config_file_location = Path::new(dir).join("fallout-terminal.yaml");
  30. if Path::is_file(&config_file_location) {
  31. return config_file_location.into_os_string().into_string().unwrap()
  32. }
  33. }
  34. }
  35. }
  36. String::from("")
  37. }
  38. pub fn load_config_file(config_file_path: String) -> Config {
  39. let mut config_file = match File::open(config_file_path.as_str()) {
  40. Ok(config_file) => config_file,
  41. Err(e) => {
  42. println!("Could not open {}: {}", config_file_path, e);
  43. exit(1);
  44. }
  45. };
  46. let mut config_str = String::new();
  47. let config: Config;
  48. match config_file.read_to_string(&mut config_str) {
  49. Ok(_) => {
  50. config = match serde_yaml::from_str(&config_str) {
  51. Ok(conf) => conf,
  52. Err(e) => {
  53. println!("Could not parse YAML in {}: {}", config_file_path, e);
  54. exit(1);
  55. }
  56. };
  57. }
  58. Err(e) => {
  59. println!("Could not read {}: {}", config_file_path, e);
  60. exit(1);
  61. }
  62. };
  63. validate(&config);
  64. config
  65. }
  66. fn validate(config: &Config) {
  67. if config.words.is_empty() {
  68. panic!("Config file validation error: word list must not be empty");
  69. }
  70. let first_len = config.words[0].len();
  71. for s in &config.words[1..] {
  72. if s.len() != first_len {
  73. panic!("Config file validation error: All words must be the same length [len({}) != len({})]", config.words[0], s);
  74. }
  75. }
  76. if config.choose > config.words.len() {
  77. panic!("'choose' value is greater than the number of available words.");
  78. }
  79. }