@@ -112,6 +112,112 @@ nonzero_integers! {
112112 #[ stable( feature = "signed_nonzero" , since = "1.34.0" ) ] NonZeroIsize ( isize ) ;
113113}
114114
115+ /// An error which can be returned when parsing a non-zero integer.
116+ ///
117+ /// # Potential causes
118+ ///
119+ /// Among other causes, `ParseNonZeroIntError` can be thrown because of leading or trailing
120+ /// whitespace in the string e.g., when it is obtained from the standard input.
121+ /// Using the [`str.trim()`] method ensures that no whitespace remains before parsing.
122+ ///
123+ /// [`str.trim()`]: ../../std/primitive.str.html#method.trim
124+ #[ unstable( feature = "nonzero_parse" , issue = "0" ) ]
125+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
126+ pub struct ParseNonZeroIntError {
127+ kind : NonZeroIntErrorKind ,
128+ }
129+
130+ /// Enum to store the various types of errors that can cause parsing a non-zero integer to fail.
131+ #[ unstable( feature = "nonzero_parse" , issue = "0" ) ]
132+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
133+ #[ non_exhaustive]
134+ pub enum NonZeroIntErrorKind {
135+ /// Value being parsed is empty.
136+ ///
137+ /// Among other causes, this variant will be constructed when parsing an empty string.
138+ Empty ,
139+ /// Contains an invalid digit.
140+ ///
141+ /// Among other causes, this variant will be constructed when parsing a string that
142+ /// contains a letter.
143+ InvalidDigit ,
144+ /// Integer is too large to store in target integer type.
145+ Overflow ,
146+ /// Integer is too small to store in target integer type.
147+ Underflow ,
148+ /// Integer contains the value `0` which is forbidden for a non-zero integer
149+ Zero ,
150+ }
151+
152+ #[ unstable( feature = "nonzero_parse" , issue = "0" ) ]
153+ impl From < ParseIntError > for ParseNonZeroIntError {
154+ fn from ( p : ParseIntError ) -> Self {
155+ use self :: IntErrorKind as IK ;
156+ use self :: NonZeroIntErrorKind as NK ;
157+ ParseNonZeroIntError {
158+ kind : match p. kind {
159+ IK :: Empty => NK :: Empty ,
160+ IK :: InvalidDigit => NK :: InvalidDigit ,
161+ IK :: Overflow => NK :: Overflow ,
162+ IK :: Underflow => NK :: Underflow ,
163+ } ,
164+ }
165+ }
166+ }
167+
168+ impl ParseNonZeroIntError {
169+ /// Outputs the detailed cause of parsing an integer failing.
170+ #[ unstable( feature = "int_error_matching" ,
171+ reason = "it can be useful to match errors when making error messages \
172+ for integer parsing",
173+ issue = "22639" ) ]
174+ pub fn kind ( & self ) -> & NonZeroIntErrorKind {
175+ & self . kind
176+ }
177+
178+ #[ unstable( feature = "int_error_internals" ,
179+ reason = "available through Error trait and this method should \
180+ not be exposed publicly",
181+ issue = "0" ) ]
182+ #[ doc( hidden) ]
183+ pub fn __description ( & self ) -> & str {
184+ match self . kind {
185+ NonZeroIntErrorKind :: Empty => "cannot parse integer from empty string" ,
186+ NonZeroIntErrorKind :: InvalidDigit => "invalid digit found in string" ,
187+ NonZeroIntErrorKind :: Overflow => "number too large to fit in target type" ,
188+ NonZeroIntErrorKind :: Underflow => "number too small to fit in target type" ,
189+ NonZeroIntErrorKind :: Zero => "number is 0" ,
190+ }
191+ }
192+
193+ }
194+
195+ #[ unstable( feature = "nonzero_parse" , issue = "0" ) ]
196+ impl fmt:: Display for ParseNonZeroIntError {
197+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
198+ self . __description ( ) . fmt ( f)
199+ }
200+ }
201+
202+
203+ macro_rules! from_str_radix_nzint_impl {
204+ ( $( $t: ty) * ) => { $(
205+ #[ unstable( feature = "nonzero_parse" , issue = "0" ) ]
206+ impl FromStr for $t {
207+ type Err = ParseNonZeroIntError ;
208+ fn from_str( src: & str ) -> Result <Self , Self :: Err > {
209+ Self :: new( from_str_radix( src, 10 ) ?)
210+ . ok_or( ParseNonZeroIntError {
211+ kind: NonZeroIntErrorKind :: Zero
212+ } )
213+ }
214+ }
215+ ) * }
216+ }
217+
218+ from_str_radix_nzint_impl ! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
219+ NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }
220+
115221/// Provides intentionally-wrapped arithmetic on `T`.
116222///
117223/// Operations like `+` on `u32` values is intended to never overflow,
0 commit comments