Slight adaptation of Ian Remmler <ian@remmler.org>'s fix in pr #39:
> If decoding into a pointer, and the pointer points to a value, decode
> into the exitsing value. Otherwise, decode into a new value and point
> to it.
> Addresses issue #38.
There is precedent for allowing strings containing digits where numbers are expected,
and so this extends that to also allow for boolean values to be given as strings.
This applies only to callers going through the decoder API. Direct access via the AST
will reflect exactly what was given in the input configuration.
Using *reflect.StructField as map key results in a data race. I honestly
do not understand why yet and can only reproduce this in the consul
codebase with high concurrency but this patch fixes it.
The same problem also exists in mitchellh/mapstructure.
A single json object with nested objects is flattened by the json parser
to a list of objects sharing the parent key. If we're decoding into
struct this was likely a mistake, and we need to re-expand the ast.
When decoding an object into a struct where the object structure doesn't
match the Go struct structure, the case tested here would panic. This
introduces additional checks to guard against the edge case being hit to
avoid the panic.
The specific checks being added are: if an item being decoded into a
struct is a literal type, the item to be decoded must be non-nil in
order to use it. This isn't super clear and to be honest I also don't
fully understand it but this fixes the problem without introducing any
more test failures and without significant code complexity.
This now gives an error instead of a panic when encountering
configuration such as described in hashicorp/terraform#5740:
```
resource "aws" "web" {
provider = "aws" {
region = "us-west-2"
}
}
```
We now return an error message - "hcl object keys must be a string"
instead of crashing.
Fixeshashicorp/terraform#5740.
Several of the esoteric syntax errors we encounter in Terraform have
bubbled up errors from the decoder. Since all these errors have a Node
in context, they can report their position which makes them _much_ more
helpful to the user, even if the error message itself is confusing.
I tried to move around PosError somewhere but got stuck finding a good
spot for it that doesn't have either a silly name or an import cycle, so
for now I'm just cross referencing into the parser package to reference
the error type.
/cc @armon - This changes how Consul has to define its structure. Ping
me tomorrow to learn more, but going to leave it here for reference too:
The Consul case (there is a test case) never worked even with go-libucl,
because there is an ambiguity of whether you want the inner children or
the array of outer elements (the slice in the Policy struct).
I've added a new modifier you can specify with a tag called "expand"
which will tell hcl to expand the value to its children for decoding.
You can see me use it in the test case which verifies that the Consul
ACLs parse.