Skip to content

Commit dc14a2b

Browse files
committed
Change behavior when both '#[display(...)]' and '#[from_str(regex = "...")]' are specified for a field, and the regular expression does not contain capture group ('(?<...>..))' or '(?P<...>...)')
Previous behavior: '#[display(...)]' was ignored New behavior: 'regex = "..."' represents the pattern in the '{}' part of '#[display(...)]'
1 parent 5a13cb8 commit dc14a2b

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

parse-display-derive/src/lib.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,12 @@ impl<'a> ParserBuilder<'a> {
362362
Ok(field.set_capture(sub_keys, &mut self.capture_next))
363363
}
364364

365-
fn push_regex(&mut self, s: &LitStr, context: &DisplayContext) -> Result<()> {
365+
fn push_regex(
366+
&mut self,
367+
s: &LitStr,
368+
context: &DisplayContext,
369+
format: &Option<DisplayFormat>,
370+
) -> Result<()> {
366371
const IDX_ESC: usize = 1;
367372
const IDX_P: usize = 2;
368373
const IDX_KEY: usize = 3;
@@ -427,6 +432,9 @@ impl<'a> ParserBuilder<'a> {
427432
}
428433
if let DisplayContext::Field { .. } = context {
429434
if !has_capture {
435+
if let Some(format) = format {
436+
return self.push_format(format, context, None, Some(&text));
437+
}
430438
let name = self.set_capture(context, &[], s.span())?;
431439
text = format!("(?<{name}>{text})");
432440
}
@@ -438,7 +446,8 @@ impl<'a> ParserBuilder<'a> {
438446
&mut self,
439447
format: &DisplayFormat,
440448
context: &DisplayContext,
441-
with: &Option<Expr>,
449+
with: Option<&Expr>,
450+
regex: Option<&str>,
442451
) -> Result<()> {
443452
for p in &format.parts {
444453
match p {
@@ -458,15 +467,18 @@ impl<'a> ParserBuilder<'a> {
458467
continue;
459468
}
460469
let c = self.set_capture(context, &keys, format.span)?;
461-
let f = format!("(?<{c}>(?s:.*?))");
462-
self.parse_format.push_hir(to_hir(&f));
470+
let mut f = format!("(?<{c}>(?s:.*?))");
463471
if keys.is_empty() {
472+
if let Some(regex) = regex {
473+
f = format!("(?<{c}>(?s:{regex}))");
474+
}
464475
if let DisplayContext::Field { field, key, .. } = context {
465476
if let Some(with_expr) = with {
466477
self.with.push(With::new(c, key, with_expr, &field.ty));
467478
}
468479
}
469480
}
481+
self.parse_format.push_hir(to_hir(&f));
470482
}
471483
}
472484
}
@@ -484,7 +496,12 @@ impl<'a> ParserBuilder<'a> {
484496
}
485497
fn push_attrs(&mut self, hattrs: &HelperAttributes, context: &DisplayContext) -> Result<()> {
486498
if !self.try_push_attrs(hattrs, context)? {
487-
self.push_format(&context.default_from_str_format()?, context, &hattrs.with)?;
499+
self.push_format(
500+
&context.default_from_str_format()?,
501+
context,
502+
hattrs.with.as_ref(),
503+
None,
504+
)?;
488505
}
489506
Ok(())
490507
}
@@ -494,10 +511,10 @@ impl<'a> ParserBuilder<'a> {
494511
context: &DisplayContext,
495512
) -> Result<bool> {
496513
Ok(if let Some(regex) = &hattrs.regex {
497-
self.push_regex(regex, context)?;
514+
self.push_regex(regex, context, &hattrs.format)?;
498515
true
499516
} else if let Some(format) = &hattrs.format {
500-
self.push_format(format, context, &hattrs.with)?;
517+
self.push_format(format, context, hattrs.with.as_ref(), None)?;
501518
true
502519
} else {
503520
false

parse-display/tests/from_str.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,25 @@ fn from_str_struct_field_regex_all() {
110110
);
111111
}
112112

113+
#[test]
114+
fn from_str_struct_field_regex_all_with_display() {
115+
#[derive(FromStr, Debug, Eq, PartialEq)]
116+
#[display("{a}, {b}")]
117+
struct TestStruct {
118+
#[display("a = {}")]
119+
#[from_str(regex = "[0-9]+")]
120+
a: u32,
121+
b: String,
122+
}
123+
assert_from_str(
124+
"a = 12, abc",
125+
TestStruct {
126+
a: 12,
127+
b: "abc".into(),
128+
},
129+
);
130+
}
131+
113132
#[test]
114133
fn from_str_struct_field_regex_self() {
115134
#[derive(FromStr, Debug, Eq, PartialEq)]
@@ -123,7 +142,7 @@ fn from_str_struct_field_regex_self() {
123142
}
124143

125144
#[test]
126-
fn from_str_struct_field_regex_self_and_display() {
145+
fn from_str_struct_field_regex_self_with_display() {
127146
#[derive(FromStr, Debug, Eq, PartialEq)]
128147
#[display("{a},{b}")]
129148
struct TestStruct {

0 commit comments

Comments
 (0)