Skip to content

Commit cabb017

Browse files
committed
feat(value): pass set errors up
1 parent 689f31f commit cabb017

File tree

2 files changed

+57
-27
lines changed

2 files changed

+57
-27
lines changed

src/lib.rs

+25-19
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
//! pflag is a port of spf13s' amazing Go package by the same name.
22
3-
#![feature(associated_type_bounds)]
43
#![feature(type_name_of_val)]
54

65
mod value;
76

87
pub use value::Slice;
98
pub use value::Value;
9+
pub use value::ValueError;
1010

1111
use std::collections::BTreeMap;
1212
use std::fmt;
@@ -51,7 +51,7 @@ pub struct Flag {
5151
}
5252

5353
impl Flag {
54-
pub fn set(&mut self, val: String) -> Result<(), String> {
54+
pub fn set(&mut self, val: String) -> Result<(), ValueError> {
5555
self.value.set(val)
5656
}
5757

@@ -534,9 +534,9 @@ impl FlagSet {
534534
builtin_flag_val!(socket_addr_v6, SocketAddrV6);
535535

536536
/// value_of retrieves the value for the given flags name.
537-
pub fn value_of<T: std::str::FromStr<Err: fmt::Debug>>(&self, name: &str) -> T {
537+
pub fn value_of<T: std::str::FromStr>(&self, name: &str) -> Result<T, T::Err> {
538538
let i = self.formal.get(name).unwrap();
539-
self.flags[*i].value.value().parse().unwrap()
539+
self.flags[*i].value.value().parse()
540540
}
541541
}
542542

@@ -651,7 +651,10 @@ mod tests {
651651
panic!(err);
652652
}
653653

654-
assert_eq!(flags.value_of::<String>("hello"), "world".to_string());
654+
assert_eq!(
655+
flags.value_of::<String>("hello").unwrap(),
656+
"world".to_string()
657+
);
655658
}
656659

657660
#[test]
@@ -663,7 +666,10 @@ mod tests {
663666
panic!(err);
664667
}
665668

666-
assert_eq!(flags.value_of::<String>("hello"), "world".to_string());
669+
assert_eq!(
670+
flags.value_of::<String>("hello").unwrap(),
671+
"world".to_string()
672+
);
667673
}
668674

669675
#[test]
@@ -675,7 +681,7 @@ mod tests {
675681
panic!(err);
676682
}
677683

678-
assert_eq!(flags.value_of::<bool>("hello"), true);
684+
assert_eq!(flags.value_of::<bool>("hello").unwrap(), true);
679685
}
680686

681687
#[test]
@@ -687,7 +693,7 @@ mod tests {
687693
panic!(err);
688694
}
689695

690-
assert_eq!(flags.value_of::<bool>("hello"), true);
696+
assert_eq!(flags.value_of::<bool>("hello").unwrap(), true);
691697
}
692698

693699
#[test]
@@ -699,7 +705,7 @@ mod tests {
699705
panic!(err);
700706
}
701707

702-
assert_eq!(flags.value_of::<bool>("help"), true);
708+
assert_eq!(flags.value_of::<bool>("help").unwrap(), true);
703709
}
704710

705711
#[test]
@@ -711,7 +717,7 @@ mod tests {
711717
panic!(err);
712718
}
713719

714-
assert_eq!(flags.value_of::<bool>("help"), true);
720+
assert_eq!(flags.value_of::<bool>("help").unwrap(), true);
715721
}
716722

717723
#[test]
@@ -724,8 +730,8 @@ mod tests {
724730
panic!(err);
725731
}
726732

727-
assert_eq!(flags.value_of::<bool>("help"), true);
728-
assert_eq!(flags.value_of::<bool>("verbose"), true);
733+
assert_eq!(flags.value_of::<bool>("help").unwrap(), true);
734+
assert_eq!(flags.value_of::<bool>("verbose").unwrap(), true);
729735
}
730736

731737
#[test]
@@ -738,8 +744,8 @@ mod tests {
738744
panic!(err);
739745
}
740746

741-
assert_eq!(flags.value_of::<bool>("help"), false);
742-
assert_eq!(flags.value_of::<bool>("verbose"), true);
747+
assert_eq!(flags.value_of::<bool>("help").unwrap(), false);
748+
assert_eq!(flags.value_of::<bool>("verbose").unwrap(), true);
743749
}
744750

745751
#[test]
@@ -751,7 +757,7 @@ mod tests {
751757
panic!(err);
752758
}
753759

754-
assert_eq!(flags.value_of::<u32>("port"), 8080);
760+
assert_eq!(flags.value_of::<u32>("port").unwrap(), 8080);
755761
}
756762

757763
#[test]
@@ -791,7 +797,7 @@ mod tests {
791797
panic!(err);
792798
}
793799

794-
let bools = flags.value_of::<Slice<bool>>("bools");
800+
let bools = flags.value_of::<Slice<bool>>("bools").unwrap();
795801
assert_eq!(bools.len(), 3);
796802
}
797803

@@ -804,7 +810,7 @@ mod tests {
804810
panic!(err);
805811
}
806812

807-
let bools = flags.value_of::<Slice<bool>>("bools");
813+
let bools = flags.value_of::<Slice<bool>>("bools").unwrap();
808814
assert_eq!(bools.len(), 3);
809815
}
810816

@@ -817,7 +823,7 @@ mod tests {
817823
panic!(err);
818824
}
819825

820-
let bools = flags.value_of::<value::Slice<bool>>("bools");
826+
let bools = flags.value_of::<value::Slice<bool>>("bools").unwrap();
821827
assert_eq!(bools.len(), 3);
822828
}
823829

@@ -830,7 +836,7 @@ mod tests {
830836
panic!(err);
831837
}
832838

833-
let bools = flags.value_of::<Slice<bool>>("bools");
839+
let bools = flags.value_of::<Slice<bool>>("bools").unwrap();
834840
assert_eq!(bools.len(), 1);
835841
}
836842
}

src/value.rs

+32-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
1+
use std::error::Error;
12
use std::fmt;
23
use std::str;
34
use std::string;
45

6+
#[derive(Debug)]
7+
pub struct ValueError(Box<dyn Error>);
8+
9+
impl fmt::Display for ValueError {
10+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11+
write!(f, "unexpected error while setting value: {}", &self.0)
12+
}
13+
}
14+
15+
impl Error for ValueError {}
16+
517
/// Value is a trait representing the value stored in a flag.
618
pub trait Value {
719
/// set sets the underlying value.
8-
fn set(&mut self, val: string::String) -> Result<(), string::String>;
20+
fn set(&mut self, val: string::String) -> Result<(), ValueError>;
921

1022
/// value retrieves the current value as a String.
1123
fn value(&self) -> string::String;
@@ -21,7 +33,11 @@ pub trait Value {
2133
}
2234
}
2335

24-
impl<T: string::ToString + str::FromStr<Err: fmt::Debug>> Value for T {
36+
impl<E, T> Value for T
37+
where
38+
E: Error + 'static,
39+
T: string::ToString + str::FromStr<Err = E>,
40+
{
2541
// typ is reimplemeted in order to leverage any::type_name, which
2642
// is currently whereas any::type_name_of_val is not.
2743
fn typ(&self) -> &str {
@@ -33,14 +49,14 @@ impl<T: string::ToString + str::FromStr<Err: fmt::Debug>> Value for T {
3349
+ 1) as usize..]
3450
}
3551

36-
fn set(&mut self, val: string::String) -> Result<(), string::String> {
52+
fn set(&mut self, val: string::String) -> Result<(), ValueError> {
3753
let res = val.as_str().parse::<T>();
3854
match res {
3955
Ok(v) => {
4056
*self = v;
4157
Ok(())
4258
}
43-
Err(err) => Err(format!("unexpected error while parsing: {:?}", err)),
59+
Err(err) => Err(ValueError(Box::new(err))),
4460
}
4561
}
4662

@@ -94,7 +110,11 @@ impl<T, V: Into<Vec<T>>> From<V> for Slice<T> {
94110
}
95111
}
96112

97-
impl<T: string::ToString + str::FromStr<Err: fmt::Debug>> Value for Slice<T> {
113+
impl<E, T> Value for Slice<T>
114+
where
115+
E: Error + 'static,
116+
T: string::ToString + str::FromStr<Err = E>,
117+
{
98118
fn typ(&self) -> &str {
99119
let type_name = std::any::type_name::<T>();
100120
&type_name[(type_name
@@ -104,7 +124,7 @@ impl<T: string::ToString + str::FromStr<Err: fmt::Debug>> Value for Slice<T> {
104124
+ 1) as usize..]
105125
}
106126

107-
fn set(&mut self, val: string::String) -> Result<(), string::String> {
127+
fn set(&mut self, val: string::String) -> Result<(), ValueError> {
108128
if !self.changed {
109129
self.vals = Vec::with_capacity(self.vals.capacity());
110130
}
@@ -115,7 +135,7 @@ impl<T: string::ToString + str::FromStr<Err: fmt::Debug>> Value for Slice<T> {
115135
self.vals.push(v);
116136
Ok(())
117137
}
118-
Err(err) => Err(format!("unexpected error while parsing: {:?}", err)),
138+
Err(err) => Err(ValueError(Box::new(err))),
119139
}
120140
})
121141
}
@@ -135,7 +155,11 @@ impl<T: string::ToString + str::FromStr<Err: fmt::Debug>> Value for Slice<T> {
135155
}
136156
}
137157

138-
impl<T: str::FromStr<Err: fmt::Debug>> str::FromStr for Slice<T> {
158+
impl<E, T> str::FromStr for Slice<T>
159+
where
160+
E: Error + 'static,
161+
T: str::FromStr<Err = E>,
162+
{
139163
type Err = T::Err;
140164

141165
fn from_str(s: &str) -> Result<Self, Self::Err> {

0 commit comments

Comments
 (0)