Browse Source

Merge pull request #463 from Demonthos/fix_escape_sequence

fix escape sequences in ifmt
Jon Kelley 3 years ago
parent
commit
22677c2992
2 changed files with 41 additions and 2 deletions
  1. 29 0
      packages/core-macro/tests/ifmt.rs
  2. 12 2
      packages/rsx/src/ifmt.rs

+ 29 - 0
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()
+    );
+}

+ 12 - 2
packages/rsx/src/ifmt.rs

@@ -14,7 +14,7 @@ pub fn format_args_f_impl(input: IfmtInput) -> Result<TokenStream> {
     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,
@@ -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 {