@@ -201,6 +201,8 @@ module Dhall.JSON (
201201 , omitNull
202202 , omitEmpty
203203 , parsePreservationAndOmission
204+ , EncodeTarget (.. )
205+ , parseEncodeTarget
204206 , Conversion (.. )
205207 , defaultConversion
206208 , convertToHomogeneousMaps
@@ -592,6 +594,32 @@ dhallToJSON e0 = loop (Core.alphaNormalize (Core.normalize e0))
592594 outer _ = Left (Unsupported e)
593595
594596 outer value
597+
598+ -- Schemas
599+ Core. Bool -> return (Aeson. String " Bool" )
600+ Core. Natural -> return (Aeson. String " Natural" )
601+ Core. Bytes -> return (Aeson. String " Bytes" )
602+ Core. Integer -> return (Aeson. String " Integer" )
603+ Core. Double -> return (Aeson. String " Double" )
604+ Core. Text -> return (Aeson. String " Text" )
605+ Core. Date -> return (Aeson. String " Date" )
606+ Core. Time -> return (Aeson. String " Time" )
607+ Core. TimeZone -> return (Aeson. String " TimeZone" )
608+ Core. App Core. List t -> do
609+ t' <- loop t
610+ return $ Aeson. Object [(" type" , Aeson. String " List" ), (" element" , t')]
611+ Core. App Core. Optional t -> do
612+ t' <- loop t
613+ return $ Aeson. Object [(" type" , Aeson. String " Optional" ), (" element" , t')]
614+ Core. Record a -> do
615+ a' <- traverse (loop . Core. recordFieldValue) a
616+ return $ Aeson. Object [(" type" , Aeson. String " Record" ), (" fields" , Aeson. toJSON (Dhall.Map. toMap a')) ]
617+ Core. Union a -> do
618+ let go Nothing = return $ Aeson. Object []
619+ go (Just t) = loop t
620+ a' <- traverse go a
621+ return $ Aeson. Object [(" type" , Aeson. String " Union" ), (" choices" , Aeson. toJSON (Dhall.Map. toMap a')) ]
622+
595623 _ -> Left (Unsupported e)
596624
597625getContents :: Expr s Void -> Maybe (Text , Maybe (Expr s Void ))
@@ -692,6 +720,22 @@ parseNullPreservation =
692720parsePreservationAndOmission :: Parser (Value -> Value )
693721parsePreservationAndOmission = parseOmission <|> parseNullPreservation
694722
723+
724+ {-| Specify whether to encode data or type as JSON (default data) -}
725+ data EncodeTarget
726+ = EncodeData
727+ | EncodeType
728+
729+ parseEncodeTarget :: Parser EncodeTarget
730+ parseEncodeTarget =
731+ Options.Applicative. flag'
732+ EncodeType
733+ ( Options.Applicative. long " type"
734+ <> Options.Applicative. help " Encode the type of the input expression instead of the value"
735+ )
736+ <|> pure EncodeData
737+
738+
695739{-| Specify whether or not to convert association lists of type
696740 @List { mapKey: Text, mapValue : v }@ to records
697741-}
@@ -1198,24 +1242,26 @@ handleSpecialDoubles specialDoubleMode =
11981242codeToValue
11991243 :: Conversion
12001244 -> SpecialDoubleMode
1245+ -> EncodeTarget
12011246 -> Maybe FilePath -- ^ The source file path. If no path is given, imports
12021247 -- are resolved relative to the current directory.
12031248 -> Text -- ^ Input text.
12041249 -> IO Value
1205- codeToValue conversion specialDoubleMode mFilePath code = do
1206- fmap snd (codeToHeaderAndValue conversion specialDoubleMode mFilePath code)
1250+ codeToValue conversion specialDoubleMode encodeTarget mFilePath code = do
1251+ fmap snd (codeToHeaderAndValue conversion specialDoubleMode encodeTarget mFilePath code)
12071252
12081253{-| This is like `codeToValue`, except also returning a `Header` that is a
12091254 valid YAML comment derived from the original Dhall code's `Header`
12101255-}
12111256codeToHeaderAndValue
12121257 :: Conversion
12131258 -> SpecialDoubleMode
1259+ -> EncodeTarget
12141260 -> Maybe FilePath -- ^ The source file path. If no path is given, imports
12151261 -- are resolved relative to the current directory.
12161262 -> Text -- ^ Input text.
12171263 -> IO (Header , Value )
1218- codeToHeaderAndValue conversion specialDoubleMode mFilePath code = do
1264+ codeToHeaderAndValue conversion specialDoubleMode encodeTarget mFilePath code = do
12191265 (Header header, parsedExpression) <- Core. throws (Dhall.Parser. exprAndHeaderFromText (fromMaybe " (input)" mFilePath) code)
12201266
12211267 let adapt line =
@@ -1231,10 +1277,15 @@ codeToHeaderAndValue conversion specialDoubleMode mFilePath code = do
12311277
12321278 resolvedExpression <- Dhall.Import. loadRelativeTo rootDirectory UseSemanticCache parsedExpression
12331279
1234- _ <- Core. throws (Dhall.TypeCheck. typeOf resolvedExpression)
1280+ t <- Core. throws (Dhall.TypeCheck. typeOf resolvedExpression)
1281+
1282+ let resolvedExpression' =
1283+ case encodeTarget of
1284+ EncodeData -> resolvedExpression
1285+ EncodeType -> t
12351286
12361287 let convertedExpression =
1237- convertToHomogeneousMaps conversion resolvedExpression
1288+ convertToHomogeneousMaps conversion resolvedExpression'
12381289
12391290 specialDoubleExpression <- Core. throws (handleSpecialDoubles specialDoubleMode convertedExpression)
12401291
0 commit comments