misfire.rs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. use std::ffi::{OsStr, OsString};
  2. use std::fmt;
  3. use std::num::ParseIntError;
  4. use glob;
  5. use options::{HelpString, VersionString};
  6. use options::parser::{Arg, Flag, ParseError};
  7. /// A list of legal choices for an argument-taking option
  8. #[derive(PartialEq, Debug)]
  9. pub struct Choices(&'static [&'static str]);
  10. impl fmt::Display for Choices {
  11. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  12. write!(f, "choices: {}", self.0.join(", "))
  13. }
  14. }
  15. /// A **misfire** is a thing that can happen instead of listing files -- a
  16. /// catch-all for anything outside the program’s normal execution.
  17. #[derive(PartialEq, Debug)]
  18. pub enum Misfire {
  19. /// The getopts crate didn’t like these Arguments.
  20. InvalidOptions(ParseError),
  21. /// The user supplied an illegal choice to an Argument.
  22. BadArgument(&'static Arg, OsString, Choices),
  23. /// The user asked for help. This isn’t strictly an error, which is why
  24. /// this enum isn’t named Error!
  25. Help(HelpString),
  26. /// The user wanted the version number.
  27. Version(VersionString),
  28. /// An option was given twice or more in strict mode.
  29. Duplicate(Flag, Flag),
  30. /// Two options were given that conflict with one another.
  31. Conflict(&'static Arg, &'static Arg),
  32. /// An option was given that does nothing when another one either is or
  33. /// isn't present.
  34. Useless(&'static Arg, bool, &'static Arg),
  35. /// An option was given that does nothing when either of two other options
  36. /// are not present.
  37. Useless2(&'static Arg, &'static Arg, &'static Arg),
  38. /// A very specific edge case where --tree can’t be used with --all twice.
  39. TreeAllAll,
  40. /// A numeric option was given that failed to be parsed as a number.
  41. FailedParse(ParseIntError),
  42. /// A glob ignore was given that failed to be parsed as a pattern.
  43. FailedGlobPattern(String),
  44. }
  45. impl Misfire {
  46. /// The OS return code this misfire should signify.
  47. pub fn is_error(&self) -> bool {
  48. match *self {
  49. Misfire::Help(_) => false,
  50. Misfire::Version(_) => false,
  51. _ => true,
  52. }
  53. }
  54. /// The Misfire that happens when an option gets given the wrong
  55. /// argument. This has to use one of the `getopts` failure
  56. /// variants--it’s meant to take just an option name, rather than an
  57. /// option *and* an argument, but it works just as well.
  58. pub fn bad_argument(option: &'static Arg, otherwise: &OsStr, legal: &'static [&'static str]) -> Misfire {
  59. Misfire::BadArgument(option, otherwise.to_os_string(), Choices(legal))
  60. }
  61. }
  62. impl From<glob::PatternError> for Misfire {
  63. fn from(error: glob::PatternError) -> Misfire {
  64. Misfire::FailedGlobPattern(error.to_string())
  65. }
  66. }
  67. impl fmt::Display for Misfire {
  68. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  69. use self::Misfire::*;
  70. match *self {
  71. BadArgument(ref a, ref b, ref c) => write!(f, "Option {} has no {:?} setting ({})", a, b, c),
  72. InvalidOptions(ref e) => write!(f, "{}", e),
  73. Help(ref text) => write!(f, "{}", text),
  74. Version(ref version) => write!(f, "{}", version),
  75. Conflict(ref a, ref b) => write!(f, "Option {} conflicts with option {}", a, b),
  76. Duplicate(ref a, ref b) => if a == b { write!(f, "Flag {} was given twice", a) }
  77. else { write!(f, "Flag {} conflicts with flag {}", a, b) },
  78. Useless(ref a, false, ref b) => write!(f, "Option {} is useless without option {}", a, b),
  79. Useless(ref a, true, ref b) => write!(f, "Option {} is useless given option {}", a, b),
  80. Useless2(ref a, ref b1, ref b2) => write!(f, "Option {} is useless without options {} or {}", a, b1, b2),
  81. TreeAllAll => write!(f, "Option --tree is useless given --all --all"),
  82. FailedParse(ref e) => write!(f, "Failed to parse number: {}", e),
  83. FailedGlobPattern(ref e) => write!(f, "Failed to parse glob pattern: {}", e),
  84. }
  85. }
  86. }
  87. impl fmt::Display for ParseError {
  88. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  89. use self::ParseError::*;
  90. match *self {
  91. NeedsValue { ref flag } => write!(f, "Flag {} needs a value", flag),
  92. ForbiddenValue { ref flag } => write!(f, "Flag {} cannot take a value", flag),
  93. UnknownShortArgument { ref attempt } => write!(f, "Unknown argument -{}", *attempt as char),
  94. UnknownArgument { ref attempt } => write!(f, "Unknown argument --{}", attempt.to_string_lossy()),
  95. }
  96. }
  97. }