diff --git a/CHANGELOG.md b/CHANGELOG.md index f6fe6f6..937a4d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,9 +9,10 @@ - removed `core.AppValue` from public interface - renamed various types to remove `-Val` and `-Term` suffixes -### Changed +### Fixed - - `dhall.Unmarshal()` now typechecks before evaluating + - `dhall.Unmarshal()` now resolves imports and typechecks before + evaluating ### Added diff --git a/testdata/unmarshal-test.dhall b/testdata/unmarshal-test.dhall new file mode 100644 index 0000000..8b991ca --- /dev/null +++ b/testdata/unmarshal-test.dhall @@ -0,0 +1 @@ +{ Port = 5050, Name = "inetd" } diff --git a/unmarshal.go b/unmarshal.go index 3fe7d16..9fbb973 100644 --- a/unmarshal.go +++ b/unmarshal.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/philandstuff/dhall-golang/core" + "github.com/philandstuff/dhall-golang/imports" "github.com/philandstuff/dhall-golang/parser" ) @@ -18,18 +19,23 @@ func isMapEntryType(recordType core.RecordType) bool { return false } -// Unmarshal takes dhall input as a byte array and parses it, -// evaluates it, and unmarshals it into the given variable. +// Unmarshal takes dhall input as a byte array and parses it, resolves +// imports, typechecks, evaluates, and unmarshals it into the given +// variable. func Unmarshal(b []byte, out interface{}) error { term, err := parser.Parse("-", b) if err != nil { return err } - _, err = core.TypeOf(term) + resolved, err := imports.Load(term) + if err != nil { + return err + } + _, err = core.TypeOf(resolved) if err != nil { return err } - Decode(core.Eval(term), out) + Decode(core.Eval(resolved), out) return nil } diff --git a/unmarshal_test.go b/unmarshal_test.go index 6ac48d2..eccf01e 100644 --- a/unmarshal_test.go +++ b/unmarshal_test.go @@ -202,7 +202,8 @@ var _ = Describe("Decode", func() { var _ = Describe("Unmarshal", func() { It("Parses 1 + 2", func() { var actual uint - Unmarshal([]byte("1 + 2"), &actual) + err := Unmarshal([]byte("1 + 2"), &actual) + Expect(err).ToNot(HaveOccurred()) Expect(actual).To(Equal(uint(3))) }) It("Throws a type error for `1 + -2`", func() { @@ -210,4 +211,14 @@ var _ = Describe("Unmarshal", func() { err := Unmarshal([]byte("1 + -2"), &actual) Expect(err).To(HaveOccurred()) }) + It("Fetches imports", func() { + type Config struct { + Port int + Name string + } + var actual Config + err := Unmarshal([]byte("./testdata/unmarshal-test.dhall"), &actual) + Expect(err).ToNot(HaveOccurred()) + Expect(actual).To(Equal(Config{Port: 5050, Name: "inetd"})) + }) })