Repository: martinohmann/hcl-rs (rust)

Issue:
Panic attempting to parse an integer
Given the following HCL:

```
resource "test" "testing" {
  ids      = [module.instance.0.id]
}
```

It leads to this panic:

```
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ParseIntError { kind: InvalidDigit }', ~/.cargo/registry/src/github.com-1ecc6299db9ec823/hcl-rs-0.8.2/src/parser/mod.rs:342:32
```

Pull request description:
fix(parser): panic when parsing `LegacyIndex` traversal operator
Fixes #83

The leading `.` was included when attempting to parse the integer index, which rightfully failed.

Patch:
diff --git a/src/parser/grammar/hcl.pest b/src/parser/grammar/hcl.pest
index 57f2d9c..1f10a08 100644
--- a/src/parser/grammar/hcl.pest
+++ b/src/parser/grammar/hcl.pest
@@ -44,7 +44,7 @@ Decimal    =  { '0'..'9' }
 
 // Collection values
 CollectionValue = _{ Tuple | Object }
-Tuple           =  { "[" ~ (Expression ~ (","? ~ Expression)* ~ ","?)? ~ "]" }
+Tuple           =  { "[" ~ (Expression ~ ("," ~ Expression)* ~ ","?)? ~ "]" }
 Object          =  { "{" ~ (ObjectItem ~ (","? ~ ObjectItem)* ~ ","?)? ~ "}" }
 ObjectItem      = _{ ObjectItemIdent | ObjectItemExpr }
 ObjectItemIdent = _{ Identifier ~ ("=" | ":") ~ Expression }
@@ -108,7 +108,7 @@ Variable = @{ Identifier }
 
 // Index operator
 Index       =  { ("[" ~ Expression ~ "]") | LegacyIndex }
-LegacyIndex = ${ "." ~ Decimal+ }
+LegacyIndex = ${ "." ~ Int }
 
 // Attribute access operator
 GetAttr = ${ "." ~ Identifier }
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index db3cf65..7a2179f 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -300,7 +300,9 @@ fn parse_traversal_operator(pair: Pair<Rule>) -> Result<TraversalOperator> {
             let pair = inner(pair);
 
             match pair.as_rule() {
-                Rule::LegacyIndex => TraversalOperator::LegacyIndex(parse_primitive::<u64>(pair)),
+                Rule::LegacyIndex => {
+                    TraversalOperator::LegacyIndex(parse_primitive::<u64>(inner(pair)))
+                }
                 _ => TraversalOperator::Index(parse_expression(pair)?),
             }
         }


Test patch:
diff --git a/src/de/tests.rs b/src/de/tests.rs
index 581a8ec..7e18f0b 100644
--- a/src/de/tests.rs
+++ b/src/de/tests.rs
@@ -463,3 +463,24 @@ fn issue_81() {
 
     assert_eq!(body, expected);
 }
+
+#[test]
+fn issue_83() {
+    let body: Body = crate::from_str("attr = module.instance.0.id").unwrap();
+
+    let expected = Body::builder()
+        .add_attribute((
+            "attr",
+            Traversal::new(
+                Identifier::new("module"),
+                [
+                    TraversalOperator::GetAttr("instance".into()),
+                    TraversalOperator::LegacyIndex(0),
+                    TraversalOperator::GetAttr("id".into()),
+                ],
+            ),
+        ))
+        .build();
+
+    assert_eq!(body, expected);
+}