Skip to content

Commit

Permalink
Change behavior when both '#[display(...)]' and '#[from_str(regex = "…
Browse files Browse the repository at this point in the history
…...")]' 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(...)]'
  • Loading branch information
frozenlib committed Jul 28, 2024
1 parent 5a13cb8 commit dc14a2b
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 8 deletions.
31 changes: 24 additions & 7 deletions parse-display-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,12 @@ impl<'a> ParserBuilder<'a> {
Ok(field.set_capture(sub_keys, &mut self.capture_next))
}

fn push_regex(&mut self, s: &LitStr, context: &DisplayContext) -> Result<()> {
fn push_regex(
&mut self,
s: &LitStr,
context: &DisplayContext,
format: &Option<DisplayFormat>,
) -> Result<()> {
const IDX_ESC: usize = 1;
const IDX_P: usize = 2;
const IDX_KEY: usize = 3;
Expand Down Expand Up @@ -427,6 +432,9 @@ impl<'a> ParserBuilder<'a> {
}
if let DisplayContext::Field { .. } = context {
if !has_capture {
if let Some(format) = format {
return self.push_format(format, context, None, Some(&text));
}
let name = self.set_capture(context, &[], s.span())?;
text = format!("(?<{name}>{text})");
}
Expand All @@ -438,7 +446,8 @@ impl<'a> ParserBuilder<'a> {
&mut self,
format: &DisplayFormat,
context: &DisplayContext,
with: &Option<Expr>,
with: Option<&Expr>,
regex: Option<&str>,
) -> Result<()> {
for p in &format.parts {
match p {
Expand All @@ -458,15 +467,18 @@ impl<'a> ParserBuilder<'a> {
continue;
}
let c = self.set_capture(context, &keys, format.span)?;
let f = format!("(?<{c}>(?s:.*?))");
self.parse_format.push_hir(to_hir(&f));
let mut f = format!("(?<{c}>(?s:.*?))");
if keys.is_empty() {
if let Some(regex) = regex {
f = format!("(?<{c}>(?s:{regex}))");
}
if let DisplayContext::Field { field, key, .. } = context {
if let Some(with_expr) = with {
self.with.push(With::new(c, key, with_expr, &field.ty));
}
}
}
self.parse_format.push_hir(to_hir(&f));
}
}
}
Expand All @@ -484,7 +496,12 @@ impl<'a> ParserBuilder<'a> {
}
fn push_attrs(&mut self, hattrs: &HelperAttributes, context: &DisplayContext) -> Result<()> {
if !self.try_push_attrs(hattrs, context)? {
self.push_format(&context.default_from_str_format()?, context, &hattrs.with)?;
self.push_format(
&context.default_from_str_format()?,
context,
hattrs.with.as_ref(),
None,
)?;
}
Ok(())
}
Expand All @@ -494,10 +511,10 @@ impl<'a> ParserBuilder<'a> {
context: &DisplayContext,
) -> Result<bool> {
Ok(if let Some(regex) = &hattrs.regex {
self.push_regex(regex, context)?;
self.push_regex(regex, context, &hattrs.format)?;
true
} else if let Some(format) = &hattrs.format {
self.push_format(format, context, &hattrs.with)?;
self.push_format(format, context, hattrs.with.as_ref(), None)?;
true
} else {
false
Expand Down
21 changes: 20 additions & 1 deletion parse-display/tests/from_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,25 @@ fn from_str_struct_field_regex_all() {
);
}

#[test]
fn from_str_struct_field_regex_all_with_display() {
#[derive(FromStr, Debug, Eq, PartialEq)]
#[display("{a}, {b}")]
struct TestStruct {
#[display("a = {}")]
#[from_str(regex = "[0-9]+")]
a: u32,
b: String,
}
assert_from_str(
"a = 12, abc",
TestStruct {
a: 12,
b: "abc".into(),
},
);
}

#[test]
fn from_str_struct_field_regex_self() {
#[derive(FromStr, Debug, Eq, PartialEq)]
Expand All @@ -123,7 +142,7 @@ fn from_str_struct_field_regex_self() {
}

#[test]
fn from_str_struct_field_regex_self_and_display() {
fn from_str_struct_field_regex_self_with_display() {
#[derive(FromStr, Debug, Eq, PartialEq)]
#[display("{a},{b}")]
struct TestStruct {
Expand Down

0 comments on commit dc14a2b

Please sign in to comment.