@@ -43,12 +43,76 @@ pub trait ModuleParam : core::fmt::Display + core::marker::Sized {
43
43
}
44
44
}
45
45
46
+ /// Trait for parsing integers. Strings begining with `0x`, `0o`, or `0b` are
47
+ /// parsed as hex, octal, or binary respectively. Strings beginning with `0`
48
+ /// otherwise are parsed as octal. Anything else is parsed as decimal. A
49
+ /// leading `+` or `-` is also permitted. Any string parsed by `kstrtol` or
50
+ /// `kstrtoul` will be successfully parsed.
51
+ trait ParseInt : Sized {
52
+ fn from_str_radix ( src : & str , radix : u32 ) -> Result < Self , core:: num:: ParseIntError > ;
53
+ fn checked_neg ( self ) -> Option < Self > ;
54
+
55
+ fn from_str_unsigned ( src : & str ) -> Result < Self , core:: num:: ParseIntError > {
56
+ let ( radix, digits) = if let Some ( n) = src. strip_prefix ( "0x" ) {
57
+ ( 16 , n)
58
+ } else if let Some ( n) = src. strip_prefix ( "0X" ) {
59
+ ( 16 , n)
60
+ } else if let Some ( n) = src. strip_prefix ( "0o" ) {
61
+ ( 8 , n)
62
+ } else if let Some ( n) = src. strip_prefix ( "0O" ) {
63
+ ( 8 , n)
64
+ } else if let Some ( n) = src. strip_prefix ( "0b" ) {
65
+ ( 2 , n)
66
+ } else if let Some ( n) = src. strip_prefix ( "0B" ) {
67
+ ( 2 , n)
68
+ } else if src. starts_with ( "0" ) {
69
+ ( 8 , src)
70
+ } else {
71
+ ( 10 , src)
72
+ } ;
73
+ Self :: from_str_radix ( digits, radix)
74
+ }
75
+
76
+ fn from_str ( src : & str ) -> Option < Self > {
77
+ match src. bytes ( ) . next ( ) {
78
+ None => None ,
79
+ Some ( b'-' ) => Self :: from_str_unsigned ( & src[ 1 ..] ) . ok ( ) ?. checked_neg ( ) ,
80
+ Some ( b'+' ) => Some ( Self :: from_str_unsigned ( & src[ 1 ..] ) . ok ( ) ?) ,
81
+ Some ( _) => Some ( Self :: from_str_unsigned ( src) . ok ( ) ?) ,
82
+ }
83
+ }
84
+ }
85
+
86
+ macro_rules! impl_parse_int {
87
+ ( $ty: ident) => {
88
+ impl ParseInt for $ty {
89
+ fn from_str_radix( src: & str , radix: u32 ) -> Result <Self , core:: num:: ParseIntError > {
90
+ $ty:: from_str_radix( src, radix)
91
+ }
92
+ fn checked_neg( self ) -> Option <Self > {
93
+ self . checked_neg( )
94
+ }
95
+ }
96
+ }
97
+ }
98
+
99
+ impl_parse_int ! ( i8 ) ;
100
+ impl_parse_int ! ( u8 ) ;
101
+ impl_parse_int ! ( i16 ) ;
102
+ impl_parse_int ! ( u16 ) ;
103
+ impl_parse_int ! ( i32 ) ;
104
+ impl_parse_int ! ( u32 ) ;
105
+ impl_parse_int ! ( i64 ) ;
106
+ impl_parse_int ! ( u64 ) ;
107
+ impl_parse_int ! ( isize ) ;
108
+ impl_parse_int ! ( usize ) ;
109
+
46
110
macro_rules! make_param_ops {
47
111
( $ops: ident, $ty: ident) => {
48
112
impl ModuleParam for $ty {
49
113
fn try_from_param_arg( arg: & [ u8 ] ) -> Option <Self > {
50
114
let utf8 = core:: str :: from_utf8( arg) . ok( ) ?;
51
- utf8 . parse :: <$ty> ( ) . ok ( )
115
+ <$ty as crate :: module_param :: ParseInt > :: from_str ( utf8 )
52
116
}
53
117
}
54
118
@@ -62,6 +126,12 @@ macro_rules! make_param_ops {
62
126
}
63
127
64
128
make_param_ops ! ( PARAM_OPS_I8 , i8 ) ;
129
+ make_param_ops ! ( PARAM_OPS_U8 , u8 ) ;
130
+ make_param_ops ! ( PARAM_OPS_I16 , i16 ) ;
131
+ make_param_ops ! ( PARAM_OPS_U16 , u16 ) ;
132
+ make_param_ops ! ( PARAM_OPS_I32 , i32 ) ;
133
+ make_param_ops ! ( PARAM_OPS_U32 , u32 ) ;
65
134
make_param_ops ! ( PARAM_OPS_I64 , i64 ) ;
66
- make_param_ops ! ( PARAM_OPS_USIZE , usize ) ;
135
+ make_param_ops ! ( PARAM_OPS_U64 , u64 ) ;
67
136
make_param_ops ! ( PARAM_OPS_ISIZE , isize ) ;
137
+ make_param_ops ! ( PARAM_OPS_USIZE , usize ) ;
0 commit comments