| 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 | 
|---|
| 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 { | 
|---|
| 68 | 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 { | 
|---|
| 95 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 
|---|
| 96 | match self { | 
|---|
| 97 | Self::None => "".fmt(f), | 
|---|
| 98 | Self::Bool(v: &bool) => v.fmt(f), | 
|---|
| 99 | Self::String(v: &String) => v.fmt(f), | 
|---|
| 100 | Self::Strings(v: &Vec) => v.join(sep: ", ").fmt(f), | 
|---|
| 101 | Self::StyledStr(v: &StyledStr) => v.fmt(f), | 
|---|
| 102 | Self::StyledStrs(v: &Vec) => { | 
|---|
| 103 | for (i: usize, v: &StyledStr) in v.iter().enumerate() { | 
|---|
| 104 | if i != 0 { | 
|---|
| 105 | ", ".fmt(f)?; | 
|---|
| 106 | } | 
|---|
| 107 | v.fmt(f)?; | 
|---|
| 108 | } | 
|---|
| 109 | Ok(()) | 
|---|
| 110 | } | 
|---|
| 111 | Self::Number(v: &isize) => v.fmt(f), | 
|---|
| 112 | } | 
|---|
| 113 | } | 
|---|
| 114 | } | 
|---|
| 115 |  | 
|---|