1 /// Semantics for a piece of error information 2 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] 3 #[non_exhaustive] 4 #[cfg(feature = "error-context")] 5 pub enum ContextKind { 6 /// The cause of the error 7 InvalidSubcommand, 8 /// The cause of the error 9 InvalidArg, 10 /// Existing arguments 11 PriorArg, 12 /// Accepted subcommands 13 ValidSubcommand, 14 /// Accepted values 15 ValidValue, 16 /// Rejected values 17 InvalidValue, 18 /// Number of values present 19 ActualNumValues, 20 /// Number of allowed values 21 ExpectedNumValues, 22 /// Minimum number of allowed values 23 MinValues, 24 /// Potential fix for the user 25 SuggestedCommand, 26 /// Potential fix for the user 27 SuggestedSubcommand, 28 /// Potential fix for the user 29 SuggestedArg, 30 /// Potential fix for the user 31 SuggestedValue, 32 /// Trailing argument 33 TrailingArg, 34 /// Potential fix for the user 35 Suggested, 36 /// A usage string 37 Usage, 38 /// An opaque message to the user 39 Custom, 40 } 41 42 impl ContextKind { 43 /// End-user description of the error case, where relevant as_str(self) -> Option<&'static str>44 pub fn as_str(self) -> Option<&'static str> { 45 match self { 46 Self::InvalidSubcommand => Some("Invalid Subcommand"), 47 Self::InvalidArg => Some("Invalid Argument"), 48 Self::PriorArg => Some("Prior Argument"), 49 Self::ValidSubcommand => Some("Valid Subcommand"), 50 Self::ValidValue => Some("Valid Value"), 51 Self::InvalidValue => Some("Invalid Value"), 52 Self::ActualNumValues => Some("Actual Number of Values"), 53 Self::ExpectedNumValues => Some("Expected Number of Values"), 54 Self::MinValues => Some("Minimum Number of Values"), 55 Self::SuggestedCommand => Some("Suggested Command"), 56 Self::SuggestedSubcommand => Some("Suggested Subcommand"), 57 Self::SuggestedArg => Some("Suggested Argument"), 58 Self::SuggestedValue => Some("Suggested Value"), 59 Self::TrailingArg => Some("Trailing Argument"), 60 Self::Suggested => Some("Suggested"), 61 Self::Usage => None, 62 Self::Custom => None, 63 } 64 } 65 } 66 67 impl std::fmt::Display for ContextKind { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result68 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 69 self.as_str().unwrap_or_default().fmt(f) 70 } 71 } 72 73 /// A piece of error information 74 #[derive(Clone, Debug, PartialEq, Eq)] 75 #[non_exhaustive] 76 #[cfg(feature = "error-context")] 77 pub enum ContextValue { 78 /// [`ContextKind`] is self-sufficient, no additional information needed 79 None, 80 /// A single value 81 Bool(bool), 82 /// A single value 83 String(String), 84 /// Many values 85 Strings(Vec<String>), 86 /// A single value 87 StyledStr(crate::builder::StyledStr), 88 /// many value 89 StyledStrs(Vec<crate::builder::StyledStr>), 90 /// A single value 91 Number(isize), 92 } 93 94 impl std::fmt::Display for ContextValue { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result95 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 96 match self { 97 Self::None => "".fmt(f), 98 Self::Bool(v) => v.fmt(f), 99 Self::String(v) => v.fmt(f), 100 Self::Strings(v) => v.join(", ").fmt(f), 101 Self::StyledStr(v) => v.fmt(f), 102 Self::StyledStrs(v) => { 103 for (i, v) in v.iter().enumerate() { 104 if i != 0 { 105 ", ".fmt(f)?; 106 } 107 v.fmt(f)?; 108 } 109 Ok(()) 110 } 111 Self::Number(v) => v.fmt(f), 112 } 113 } 114 } 115