Skip to content
This repository has been archived by the owner on Oct 3, 2019. It is now read-only.

Marshal/ Unmarshal like in encoding/json #42

Closed
mattes opened this issue Jul 27, 2018 · 2 comments
Closed

Marshal/ Unmarshal like in encoding/json #42

mattes opened this issue Jul 27, 2018 · 2 comments

Comments

@mattes
Copy link

mattes commented Jul 27, 2018

I'm looking for two simple functions:

func Marshal(v interface{}) ([]byte, error)
func Unmarshal(data []byte, v interface{}) error

Compare with encoding/json.Marshal and encoding/json.Unmarshal.

Unmarshal ...

I was able to get the Unmarshal working with:

func Unmarshal(data []byte, v interface{}) error {
	parser := hclparse.NewParser()
	file, diag := parser.ParseHCL(data, "<data>")
	if diag.HasErrors() {
		return diag
	}

	diag = gohcl.DecodeBody(file.Body, nil, v)
	if diag.HasErrors() {
		return diag
	}
	return nil
}

Where v interface{} must include hcl struct tags, or it will return errors.

Marshal?

Can someone point me in the right direction for the Marshal function?

@apparentlymart
Copy link
Member

Hi @mattes! Thanks for this question.

HCL is intended as a configuration language rather than as a generic serialization language, and so its API is (as you've seen) a little different than the various "encoding" packages in Go.

In particular, the main HCL API is an abstraction over multiple syntaxes (currently HCL native and JSON) and so the parsing and decoding steps are separated to allow the decoding to be syntax-agnostic while the parsing is (naturally) syntax-specific.

Code generation must also always be syntax-specific. We don't currently have any facility here for generating HCL-as-JSON, but we do have package hclwrite for generating the native syntax. It is a separate package because its API is designed around a physical syntax tree rather than the usual syntax-agnostic model.

Using this API directly gives the most flexibility in how the result is generated (order of body items, spacing between items, etc) but (as @SimonRichardson noticed) there is also a higher-level helper function in gohcl for driving hclwrite, supporting a subset of the struct tags.

This helper is pretty new and I think it wasn't there when this issue was first opened. Since HCL development so far has been prioritizing what Terraform needs (with it being the first big user of the new implementation), hclwrite and this gohcl.EncodeIntoBody function have not yet been put to the test in real use, so they may have bugs, but they are working at least to the extent illustrated in the godoc examples.

I expect we will continue to improve these facilities in future, once the basic HCL functionality is stable. For now though I'm going to close this out since the initial functionality is present. If you try to use these generation functions and find bugs, please feel free to open new issues for them and we will try to get them fixed.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants