Skip to content

Commit

Permalink
Optionally allow missing lists in yaml/json-to-dhall
Browse files Browse the repository at this point in the history
  • Loading branch information
akshaymankar committed Oct 11, 2019
1 parent a24ddfc commit 670bc24
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 12 deletions.
34 changes: 25 additions & 9 deletions dhall-json/src/Dhall/JSONToDhall.hs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ parseConversion = Conversion <$> parseStrict
<*> parseKVArr
<*> parseKVMap
<*> parseUnion
<*> parseOmissibleLists
where
parseStrict =
O.flag' True
Expand All @@ -275,6 +276,10 @@ parseConversion = Conversion <$> parseStrict
( O.long "no-keyval-maps"
<> O.help "Disable conversion of homogeneous map objects to association lists"
)
parseOmissibleLists = O.switch
( O.long "omissible-lists"
<> O.help "Tolerate missing list values, they are assumed empty"
)

-- | Parser for command options related to treating union types
parseUnion :: Parser UnionConv
Expand Down Expand Up @@ -303,21 +308,23 @@ parseUnion =

-- | JSON-to-dhall translation options
data Conversion = Conversion
{ strictRecs :: Bool
, noKeyValArr :: Bool
, noKeyValMap :: Bool
, unions :: UnionConv
{ strictRecs :: Bool
, noKeyValArr :: Bool
, noKeyValMap :: Bool
, unions :: UnionConv
, omissibleLists :: Bool
} deriving Show

data UnionConv = UFirst | UNone | UStrict deriving (Show, Read, Eq)

-- | Default conversion options
defaultConversion :: Conversion
defaultConversion = Conversion
{ strictRecs = False
, noKeyValArr = False
, noKeyValMap = False
, unions = UFirst
defaultConversion = Conversion
{ strictRecs = False
, noKeyValArr = False
, noKeyValMap = False
, unions = UFirst
, omissibleLists = False
}

-- | The 'Expr' type concretization used throughout this module
Expand Down Expand Up @@ -416,6 +423,9 @@ dhallFromJSON (Conversion {..}) expressionType =
= loop t value
| App D.Optional t' <- t
= Right (App D.None t')
| App D.List _ <- t
, omissibleLists
= Right (D.ListLit (Just t) [])
| otherwise
= Left (MissingKey k t v)
in D.RecordLit <$> Map.traverseWithKey f r
Expand Down Expand Up @@ -470,6 +480,12 @@ dhallFromJSON (Conversion {..}) expressionType =
(Seq.fromList es)
in f <$> traverse (loop t) (toList a)

-- null ~> List
loop t@(App D.List _) (A.Null)
= if omissibleLists
then Right (D.ListLit (Just t) [])
else Left (Mismatch t A.Null)

-- number ~> Integer
loop D.Integer (A.Number x)
| Right n <- floatingOrInteger x :: Either Double Integer
Expand Down
12 changes: 9 additions & 3 deletions dhall-json/tasty/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ testTree =
, testJSONToDhall "./tasty/data/emptyList"
, testJSONToDhall "./tasty/data/emptyObjectStrongType"
, testJSONToDhall "./tasty/data/emptyListStrongType"
, testCustomConversionJSONToDhall omissibleLists "./tasty/data/missingList"
, Test.Tasty.testGroup "Nesting"
[ testDhallToJSON "./tasty/data/nesting0"
, testDhallToJSON "./tasty/data/nesting1"
Expand All @@ -57,6 +58,7 @@ testTree =
, testDhallToJSON "./tasty/data/unionKeys"
]
]
where omissibleLists = JSONToDhall.defaultConversion{JSONToDhall.omissibleLists = True}

testDhallToJSON :: String -> TestTree
testDhallToJSON prefix = Test.Tasty.HUnit.testCase prefix $ do
Expand Down Expand Up @@ -92,8 +94,9 @@ testDhallToJSON prefix = Test.Tasty.HUnit.testCase prefix $ do

Test.Tasty.HUnit.assertEqual message expectedValue actualValue

testJSONToDhall :: String -> TestTree
testJSONToDhall prefix = Test.Tasty.HUnit.testCase prefix $ do
testCustomConversionJSONToDhall :: JSONToDhall.Conversion -> String -> TestTree
testCustomConversionJSONToDhall conv prefix =
Test.Tasty.HUnit.testCase prefix $ do
let inputFile = prefix <> ".json"
let schemaFile = prefix <> "Schema.dhall"
let outputFile = prefix <> ".dhall"
Expand All @@ -114,7 +117,7 @@ testJSONToDhall prefix = Test.Tasty.HUnit.testCase prefix $ do
_ <- Core.throws (Dhall.TypeCheck.typeOf schema)

actualExpression <- do
Core.throws (JSONToDhall.dhallFromJSON JSONToDhall.defaultConversion schema value)
Core.throws (JSONToDhall.dhallFromJSON conv schema value)

outputText <- Data.Text.IO.readFile outputFile

Expand All @@ -132,6 +135,9 @@ testJSONToDhall prefix = Test.Tasty.HUnit.testCase prefix $ do

Test.Tasty.HUnit.assertEqual message expectedExpression actualExpression

testJSONToDhall :: String -> TestTree
testJSONToDhall = testCustomConversionJSONToDhall JSONToDhall.defaultConversion

testDhallToYaml :: Dhall.Yaml.Options -> String -> TestTree
testDhallToYaml options prefix = Test.Tasty.HUnit.testCase prefix $ do
let inputFile = prefix <> ".dhall"
Expand Down
1 change: 1 addition & 0 deletions dhall-json/tasty/data/missingList.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{present = ["some-stuff"], null = [] : List Text, missing = [] : List Text}
1 change: 1 addition & 0 deletions dhall-json/tasty/data/missingList.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"present": ["some-stuff"], "null": null}
1 change: 1 addition & 0 deletions dhall-json/tasty/data/missingListSchema.dhall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{present : List Text, null : List Text, missing : List Text}

0 comments on commit 670bc24

Please sign in to comment.