From 41ad6179d169a1a2b6d0fc55adcc53931acd3d91 Mon Sep 17 00:00:00 2001
From: Tom Alexander <tom@fizz.buzz>
Date: Tue, 28 Apr 2020 19:02:43 -0400
Subject: [PATCH] Parse self-references and add a test for sections.

---
 js/test_cases/dot_reference/input1.json | 1 +
 js/test_cases/dot_reference/main.dust   | 3 +++
 js/test_cases/sections/input1.json      | 1 +
 js/test_cases/sections/input10.json     | 1 +
 js/test_cases/sections/input2.json      | 1 +
 js/test_cases/sections/input3.json      | 1 +
 js/test_cases/sections/input4.json      | 1 +
 js/test_cases/sections/input5.json      | 1 +
 js/test_cases/sections/input6.json      | 1 +
 js/test_cases/sections/input7.json      | 1 +
 js/test_cases/sections/input8.json      | 1 +
 js/test_cases/sections/input9.json      | 1 +
 js/test_cases/sections/main.dust        | 5 +++++
 src/parser/parser.rs                    | 8 +++++++-
 14 files changed, 26 insertions(+), 1 deletion(-)
 create mode 100644 js/test_cases/dot_reference/input1.json
 create mode 100644 js/test_cases/dot_reference/main.dust
 create mode 100644 js/test_cases/sections/input1.json
 create mode 100644 js/test_cases/sections/input10.json
 create mode 100644 js/test_cases/sections/input2.json
 create mode 100644 js/test_cases/sections/input3.json
 create mode 100644 js/test_cases/sections/input4.json
 create mode 100644 js/test_cases/sections/input5.json
 create mode 100644 js/test_cases/sections/input6.json
 create mode 100644 js/test_cases/sections/input7.json
 create mode 100644 js/test_cases/sections/input8.json
 create mode 100644 js/test_cases/sections/input9.json
 create mode 100644 js/test_cases/sections/main.dust

diff --git a/js/test_cases/dot_reference/input1.json b/js/test_cases/dot_reference/input1.json
new file mode 100644
index 0000000..fee95a9
--- /dev/null
+++ b/js/test_cases/dot_reference/input1.json
@@ -0,0 +1 @@
+{"names": ["Alice", "Bob", "Chris"]}
diff --git a/js/test_cases/dot_reference/main.dust b/js/test_cases/dot_reference/main.dust
new file mode 100644
index 0000000..b9709ca
--- /dev/null
+++ b/js/test_cases/dot_reference/main.dust
@@ -0,0 +1,3 @@
+{#names}
+Hello {.}!
+{/names}
diff --git a/js/test_cases/sections/input1.json b/js/test_cases/sections/input1.json
new file mode 100644
index 0000000..69197e0
--- /dev/null
+++ b/js/test_cases/sections/input1.json
@@ -0,0 +1 @@
+{"things": ["Alice", "Bob", "Chris"]}
diff --git a/js/test_cases/sections/input10.json b/js/test_cases/sections/input10.json
new file mode 100644
index 0000000..08f519d
--- /dev/null
+++ b/js/test_cases/sections/input10.json
@@ -0,0 +1 @@
+{"things": {}}
diff --git a/js/test_cases/sections/input2.json b/js/test_cases/sections/input2.json
new file mode 100644
index 0000000..4743329
--- /dev/null
+++ b/js/test_cases/sections/input2.json
@@ -0,0 +1 @@
+{"things": {"name": "Alice", "keyboard": "K-Type"}}
diff --git a/js/test_cases/sections/input3.json b/js/test_cases/sections/input3.json
new file mode 100644
index 0000000..8040d63
--- /dev/null
+++ b/js/test_cases/sections/input3.json
@@ -0,0 +1 @@
+{"there_are_no_things": 4}
diff --git a/js/test_cases/sections/input4.json b/js/test_cases/sections/input4.json
new file mode 100644
index 0000000..03d1e8a
--- /dev/null
+++ b/js/test_cases/sections/input4.json
@@ -0,0 +1 @@
+{"things": "just a string"}
diff --git a/js/test_cases/sections/input5.json b/js/test_cases/sections/input5.json
new file mode 100644
index 0000000..4ef7571
--- /dev/null
+++ b/js/test_cases/sections/input5.json
@@ -0,0 +1 @@
+{"things": false}
diff --git a/js/test_cases/sections/input6.json b/js/test_cases/sections/input6.json
new file mode 100644
index 0000000..feb65c6
--- /dev/null
+++ b/js/test_cases/sections/input6.json
@@ -0,0 +1 @@
+{"things": null}
diff --git a/js/test_cases/sections/input7.json b/js/test_cases/sections/input7.json
new file mode 100644
index 0000000..d9fc4f8
--- /dev/null
+++ b/js/test_cases/sections/input7.json
@@ -0,0 +1 @@
+{"things": 0}
diff --git a/js/test_cases/sections/input8.json b/js/test_cases/sections/input8.json
new file mode 100644
index 0000000..1486a8a
--- /dev/null
+++ b/js/test_cases/sections/input8.json
@@ -0,0 +1 @@
+{"things": ""}
diff --git a/js/test_cases/sections/input9.json b/js/test_cases/sections/input9.json
new file mode 100644
index 0000000..93babc6
--- /dev/null
+++ b/js/test_cases/sections/input9.json
@@ -0,0 +1 @@
+{"things": []}
diff --git a/js/test_cases/sections/main.dust b/js/test_cases/sections/main.dust
new file mode 100644
index 0000000..7394d2b
--- /dev/null
+++ b/js/test_cases/sections/main.dust
@@ -0,0 +1,5 @@
+{#things}
+Thing: {.}
+{:else}
+No things
+{/things}
diff --git a/src/parser/parser.rs b/src/parser/parser.rs
index 4e49bc7..25fc802 100644
--- a/src/parser/parser.rs
+++ b/src/parser/parser.rs
@@ -58,6 +58,9 @@ pub struct Comment<'a> {
     value: &'a str,
 }
 
+/// A series of keys separated by '.' to reference a variable in the context
+///
+/// Special case: If the path is just "." then keys will be an empty vec
 #[derive(Clone, Debug, PartialEq)]
 pub struct Path<'a> {
     pub keys: Vec<&'a str>,
@@ -197,7 +200,10 @@ fn key(i: &str) -> IResult<&str, &str> {
 
 /// A series of keys separated by '.' to reference a variable in the context
 fn path(i: &str) -> IResult<&str, Path> {
-    map(separated_list1(tag("."), key), |body| Path { keys: body })(i)
+    alt((
+        map(separated_list1(tag("."), key), |body| Path { keys: body }),
+        value(Path { keys: Vec::new() }, tag(".")),
+    ))(i)
 }
 
 /// Either a literal or a path to a value