diff --git a/packages/core-macro/tests/ifmt.rs b/packages/core-macro/tests/ifmt.rs new file mode 100644 index 000000000..52ac347b3 --- /dev/null +++ b/packages/core-macro/tests/ifmt.rs @@ -0,0 +1,29 @@ +use std::borrow::Borrow; + +use dioxus_core_macro::*; + +#[test] +fn formatting_compiles() { + let x = (0, 1); + // escape sequences work + assert_eq!( + format_args_f!("{x:?} {{}}}}").to_string(), + format!("{:?} {{}}}}", x).to_string() + ); + assert_eq!( + format_args_f!("{{{{}} {x:?}").to_string(), + format!("{{{{}} {:?}", x).to_string() + ); + + // paths in formating works + assert_eq!( + format_args_f!("{x.0}").to_string(), + format!("{}", x.0).to_string() + ); + + // function calls in formatings work + assert_eq!( + format_args_f!("{x.borrow():?}").to_string(), + format!("{:?}", x.borrow()).to_string() + ); +} diff --git a/packages/rsx/src/ifmt.rs b/packages/rsx/src/ifmt.rs index 2d77a243f..58d52c7d1 100644 --- a/packages/rsx/src/ifmt.rs +++ b/packages/rsx/src/ifmt.rs @@ -14,7 +14,7 @@ pub fn format_args_f_impl(input: IfmtInput) -> Result { let mut expr_counter = 0; for segment in input.segments.iter() { match segment { - Segment::Literal(s) => format_literal += s, + Segment::Literal(s) => format_literal += &s.replace('{', "{{").replace('}', "}}"), Segment::Formatted { format_args, segment, @@ -94,7 +94,7 @@ impl FromStr for IfmtInput { while let Some(c) = chars.next() { if c == ':' { let mut current_format_args = String::new(); - for c in chars.by_ref() { + while let Some(c) = chars.next() { if c == '}' { segments.push(Segment::Formatted { format_args: current_format_args, @@ -116,6 +116,17 @@ impl FromStr for IfmtInput { current_captured.push(c); } } else { + if '}' == c { + if let Some(c) = chars.next_if(|c| *c == '}') { + current_literal.push(c); + continue; + } else { + return Err(Error::new( + Span::call_site(), + "unmatched closing '}' in format string", + )); + } + } current_literal.push(c); } } @@ -146,7 +157,6 @@ impl FormattedSegment { return Ok(Self::Ident(ident)); } } - // if let Ok(expr) = parse_str(&("{".to_string() + input + "}")) { if let Ok(expr) = parse_str(input) { Ok(Self::Expr(Box::new(expr))) } else {