{-# OPTIONS_GHC -fno-warn-orphans #-} -- These optimizations are disabled to improve compile times (and compilation -- memory usage). When we do not disable them, the CI servers take more than -- 10 minutes to compile this module alone. -- Having looked into aeson and how the instances are written, I still do -- not understand what makes GHC choke so much here. The size of the raw -- expressions below looks fairly negligible, so there must be some expansion -- due to inlining going on. But even disabling INLINE pragmas in aeson did -- not seem to change anything. -- Nonetheless, this solution works and has no downsides because the -- instances defined here are not in any way performance-critical. {-# OPTIONS_GHC -fno-pre-inlining #-} {-# OPTIONS_GHC -fno-specialise #-} {-# OPTIONS_GHC -fignore-interface-pragmas #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE NoImplicitPrelude #-} module Language.Haskell.Brittany.Internal.Config.Types.Instances where import qualified Data.Aeson.Key as Key import qualified Data.Aeson.Types as Aeson import Data.Yaml import Language.Haskell.Brittany.Internal.Config.Types import Language.Haskell.Brittany.Internal.Prelude aesonDecodeOptionsBrittany :: Aeson.Options aesonDecodeOptionsBrittany = Aeson.defaultOptions { Aeson.omitNothingFields = True , Aeson.fieldLabelModifier = dropWhile (=='_') } instance FromJSON (CDebugConfig Maybe) where parseJSON = Aeson.genericParseJSON aesonDecodeOptionsBrittany instance ToJSON (CDebugConfig Maybe) where toJSON = Aeson.genericToJSON aesonDecodeOptionsBrittany instance FromJSON IndentPolicy where parseJSON = Aeson.genericParseJSON aesonDecodeOptionsBrittany instance ToJSON IndentPolicy where toJSON = Aeson.genericToJSON aesonDecodeOptionsBrittany toEncoding = Aeson.genericToEncoding aesonDecodeOptionsBrittany instance FromJSON AltChooser where parseJSON = Aeson.genericParseJSON aesonDecodeOptionsBrittany instance ToJSON AltChooser where toJSON = Aeson.genericToJSON aesonDecodeOptionsBrittany toEncoding = Aeson.genericToEncoding aesonDecodeOptionsBrittany instance FromJSON ColumnAlignMode where parseJSON = Aeson.genericParseJSON aesonDecodeOptionsBrittany instance ToJSON ColumnAlignMode where toJSON = Aeson.genericToJSON aesonDecodeOptionsBrittany toEncoding = Aeson.genericToEncoding aesonDecodeOptionsBrittany instance FromJSON CPPMode where parseJSON = Aeson.genericParseJSON aesonDecodeOptionsBrittany instance ToJSON CPPMode where toJSON = Aeson.genericToJSON aesonDecodeOptionsBrittany toEncoding = Aeson.genericToEncoding aesonDecodeOptionsBrittany instance FromJSON ExactPrintFallbackMode where parseJSON = Aeson.genericParseJSON aesonDecodeOptionsBrittany instance ToJSON ExactPrintFallbackMode where toJSON = Aeson.genericToJSON aesonDecodeOptionsBrittany toEncoding = Aeson.genericToEncoding aesonDecodeOptionsBrittany instance FromJSON (CLayoutConfig Maybe) where parseJSON = Aeson.genericParseJSON aesonDecodeOptionsBrittany instance ToJSON (CLayoutConfig Maybe) where toJSON = Aeson.genericToJSON aesonDecodeOptionsBrittany instance FromJSON (CErrorHandlingConfig Maybe) where parseJSON = Aeson.genericParseJSON aesonDecodeOptionsBrittany instance ToJSON (CErrorHandlingConfig Maybe) where toJSON = Aeson.genericToJSON aesonDecodeOptionsBrittany instance FromJSON (CForwardOptions Maybe) where parseJSON = Aeson.genericParseJSON aesonDecodeOptionsBrittany instance ToJSON (CForwardOptions Maybe) where toJSON = Aeson.genericToJSON aesonDecodeOptionsBrittany instance FromJSON (CPreProcessorConfig Maybe) where parseJSON = Aeson.genericParseJSON aesonDecodeOptionsBrittany instance ToJSON (CPreProcessorConfig Maybe) where toJSON = Aeson.genericToJSON aesonDecodeOptionsBrittany instance ToJSON (CConfig Maybe) where toJSON = Aeson.genericToJSON aesonDecodeOptionsBrittany -- This custom instance ensures the "omitNothingFields" behaviour not only for -- leafs, but for nodes of the config as well. This way e.g. "{}" is valid -- config file content. instance FromJSON (CConfig Maybe) where parseJSON (Object v) = Config <$> v .:? Key.fromString "conf_version" <*> v .:?= Key.fromString "conf_debug" <*> v .:?= Key.fromString "conf_layout" <*> v .:?= Key.fromString "conf_errorHandling" <*> v .:?= Key.fromString "conf_forward" <*> v .:?= Key.fromString "conf_preprocessor" <*> v .:? Key.fromString "conf_roundtrip_exactprint_only" <*> v .:? Key.fromString "conf_disable_formatting" <*> v .:? Key.fromString "conf_obfuscate" parseJSON invalid = Aeson.typeMismatch "Config" invalid -- Pretends that the value is {} when the key is not present. (.:?=) :: FromJSON a => Object -> Key.Key -> Parser a o .:?= k = o .:? k >>= maybe (parseJSON (Aeson.object [])) pure