arg.rs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // This file is licensed under the terms of 0BSD:
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any purpose with or without
  4. // fee is hereby granted.
  5. //
  6. // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  7. // SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  8. // AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  9. // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  10. // NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  11. // OF THIS SOFTWARE.
  12. //
  13. use std::env;
  14. use std::ffi::OsString;
  15. use std::path::PathBuf;
  16. use std::process::exit;
  17. use std::str::FromStr;
  18. fn usage() -> ! {
  19. let name = env::args().next().unwrap();
  20. eprintln!(
  21. "usage: {} [-rR] [-c CONFIG] [-d OUT_DIR] -m MAIDLIR
  22. MAILDIR A directory containing the maildirs of lists you want to parse
  23. FLAGS (default -gh if none set)
  24. -h include HTML output
  25. ARGS:
  26. -c config file (crabmail.conf)
  27. -d output directory
  28. -m maildir directory (mandatory)",
  29. name
  30. );
  31. exit(1)
  32. }
  33. #[derive(Default)]
  34. pub struct Args {
  35. pub config: PathBuf,
  36. pub out_dir: PathBuf,
  37. pub maildir: PathBuf,
  38. pub positional: Vec<OsString>,
  39. pub include_html: bool,
  40. }
  41. impl Args {
  42. pub fn default() -> Self {
  43. Args {
  44. out_dir: "site".into(),
  45. config: "crabmail.conf".into(),
  46. ..Default::default()
  47. }
  48. }
  49. pub fn from_env() -> Self {
  50. let mut out = Self::default();
  51. let mut args = env::args_os().skip(1);
  52. while let Some(arg) = args.next() {
  53. let s = arg.to_string_lossy();
  54. let mut ch_iter = s.chars();
  55. if ch_iter.next() != Some('-') {
  56. out.positional.push(arg);
  57. continue;
  58. }
  59. ch_iter.for_each(|m| match m {
  60. // Edit these lines //
  61. 'c' => out.config = parse_os_arg(args.next()),
  62. 'd' => out.out_dir = parse_os_arg(args.next()),
  63. 'm' => out.maildir = parse_os_arg(args.next()),
  64. 'h' => out.include_html = true,
  65. // Stop editing //
  66. _ => {
  67. usage();
  68. }
  69. })
  70. }
  71. out
  72. }
  73. }
  74. #[allow(dead_code)]
  75. fn parse_arg<T: FromStr>(a: Option<OsString>) -> T {
  76. a.and_then(|a| a.into_string().ok())
  77. .and_then(|a| a.parse().ok())
  78. .unwrap_or_else(|| usage())
  79. }
  80. fn parse_os_arg<T: From<OsString>>(a: Option<OsString>) -> T {
  81. match a {
  82. Some(s) => T::from(s),
  83. None => usage(),
  84. }
  85. }