Skip to content

Commit 14ead5d

Browse files
committed
separate FromStr implementation for Tagged
1 parent 86c3605 commit 14ead5d

File tree

2 files changed

+68
-103
lines changed

2 files changed

+68
-103
lines changed

rust/functora-tagged/src/lib.rs

Lines changed: 41 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -12,67 +12,64 @@ where
1212
Rep: Refine<Tag>;
1313

1414
pub trait Refine<Tag>:
15-
Eq + PartialEq + Ord + PartialOrd + Clone + Debug + FromStr
15+
Eq + PartialEq + Ord + PartialOrd + Clone + Debug
1616
{
17-
type DecodeErr: Debug
18-
+ Display
19-
+ From<<Self as FromStr>::Err>;
20-
21-
fn decode(txt: &str) -> Result<Self, Self::DecodeErr> {
22-
Self::from_str(txt).map_err(Self::DecodeErr::from)
23-
}
24-
25-
type RefineErr: Debug + Display;
26-
27-
fn refine(rep: Self) -> Result<Self, Self::RefineErr> {
28-
Ok(rep)
17+
type RefineErrorRep: Debug + Display;
18+
fn refine(self) -> Result<Self, Self::RefineErrorRep> {
19+
Ok(self)
2920
}
3021
}
3122

3223
#[derive(Debug, Error)]
33-
pub enum Error<Rep, Tag>
24+
#[error("Refine error: {0}")]
25+
pub struct RefineError<Rep, Tag>(pub Rep::RefineErrorRep)
3426
where
35-
Rep: Refine<Tag>,
36-
{
37-
#[error("Tagged Decode error: {0}")]
38-
Decode(Rep::DecodeErr),
39-
40-
#[error("Tagged Refine error: {0}")]
41-
Refine(Rep::RefineErr),
42-
}
27+
Rep: Refine<Tag>;
4328

4429
impl<Rep, Tag> Tagged<Rep, Tag>
4530
where
4631
Rep: Refine<Tag>,
4732
{
48-
pub fn new(rep: Rep) -> Result<Self, Error<Rep, Tag>> {
49-
Rep::refine(rep)
33+
pub fn new(
34+
rep: Rep,
35+
) -> Result<Self, RefineError<Rep, Tag>> {
36+
rep.refine()
5037
.map(|rep| Tagged(rep, PhantomData))
51-
.map_err(Error::Refine)
38+
.map_err(RefineError)
5239
}
53-
5440
pub fn rep(self) -> Rep {
5541
self.0
5642
}
5743
}
5844

59-
impl<Rep, Tag> FromStr for Tagged<Rep, Tag>
45+
#[derive(Debug, Error)]
46+
pub enum ParseError<Rep, Tag>
6047
where
61-
Rep: Refine<Tag>,
48+
Rep: FromStr + Refine<Tag>,
6249
{
63-
type Err = Error<Rep, Tag>;
50+
#[error("Decode failed: {0}")]
51+
Decode(Rep::Err),
52+
#[error("Refine failed: {0}")]
53+
Refine(RefineError<Rep, Tag>),
54+
}
6455

65-
fn from_str(txt: &str) -> Result<Self, Self::Err> {
66-
Rep::decode(txt)
67-
.map_err(Error::Decode)
68-
.and_then(Tagged::new)
56+
impl<Rep, Tag> FromStr for Tagged<Rep, Tag>
57+
where
58+
Rep: FromStr + Refine<Tag>,
59+
{
60+
type Err = ParseError<Rep, Tag>;
61+
fn from_str(s: &str) -> Result<Self, Self::Err> {
62+
Tagged::new(
63+
Rep::from_str(s).map_err(ParseError::Decode)?,
64+
)
65+
.map_err(ParseError::Refine)
6966
}
7067
}
7168

7269
#[cfg(feature = "serde")]
7370
impl<Rep, Tag> Serialize for Tagged<Rep, Tag>
7471
where
75-
Rep: Refine<Tag> + Serialize,
72+
Rep: Serialize + Refine<Tag>,
7673
{
7774
fn serialize<S>(
7875
&self,
@@ -86,20 +83,20 @@ where
8683
}
8784

8885
#[cfg(feature = "serde")]
89-
impl<'a, Rep, Tag> Deserialize<'a> for Tagged<Rep, Tag>
86+
impl<'de, Rep, Tag> Deserialize<'de> for Tagged<Rep, Tag>
9087
where
91-
Rep: Refine<Tag>,
88+
Rep: FromStr + Refine<Tag>,
89+
Rep::Err: Debug + Display,
9290
{
9391
fn deserialize<D>(
9492
deserializer: D,
9593
) -> Result<Self, D::Error>
9694
where
97-
D: serde::Deserializer<'a>,
95+
D: serde::Deserializer<'de>,
9896
{
99-
Tagged::<Rep, Tag>::from_str(&String::deserialize(
100-
deserializer,
101-
)?)
102-
.map_err(serde::de::Error::custom)
97+
let s = String::deserialize(deserializer)?;
98+
Tagged::from_str(&s)
99+
.map_err(serde::de::Error::custom)
103100
}
104101
}
105102

@@ -120,9 +117,8 @@ mod diesel_impl {
120117
{
121118
type Expression =
122119
<Rep as AsExpression<ST>>::Expression;
123-
124120
fn as_expression(self) -> Self::Expression {
125-
self.0.clone().as_expression()
121+
self.0.as_expression()
126122
}
127123
}
128124

@@ -133,7 +129,6 @@ mod diesel_impl {
133129
{
134130
type Expression =
135131
<Rep as AsExpression<ST>>::Expression;
136-
137132
fn as_expression(self) -> Self::Expression {
138133
self.0.clone().as_expression()
139134
}
@@ -165,8 +160,7 @@ mod diesel_impl {
165160
) -> diesel::deserialize::Result<Self> {
166161
let rep = Rep::from_sql(bytes)?;
167162
Tagged::new(rep).map_err(|e| {
168-
format!("Tagged decode/refine failed: {e}")
169-
.into()
163+
format!("Refine failed: {e}").into()
170164
})
171165
}
172166
}
@@ -181,15 +175,13 @@ mod diesel_impl {
181175
DB: Backend,
182176
{
183177
type Row = <Rep as Queryable<ST, DB>>::Row;
184-
185178
fn build(
186179
row: Self::Row,
187180
) -> diesel::deserialize::Result<Self> {
188181
let rep =
189182
<Rep as Queryable<ST, DB>>::build(row)?;
190183
Tagged::new(rep).map_err(|e| {
191-
format!("Tagged decode/refine failed: {e}")
192-
.into()
184+
format!("Refine failed: {e}").into()
193185
})
194186
}
195187
}

0 commit comments

Comments
 (0)