cabal2json-0.0.0.0: src/Cabal2JSON.hs
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Cabal2JSON
( cabal2JSON,
)
where
import Autodocodec
import Control.Arrow (first)
import Data.Aeson (FromJSON, ToJSON)
import qualified Data.ByteString.Char8 as SB8
import qualified Data.ByteString.Lazy as LB
import qualified Data.HashMap.Strict as HM
import Data.Hashable
import qualified Data.List.NonEmpty as NE
import qualified Data.Text as T
import Data.Text.Encoding
import Distribution.Compiler as Cabal
import Distribution.License as Cabal
import Distribution.ModuleName as Cabal
import Distribution.PackageDescription
import Distribution.PackageDescription.Parsec as Cabal
import Distribution.Parsec (eitherParsec)
import Distribution.Pretty as Pretty
import Distribution.SPDX (LicenseExpression (..), SimpleLicenseExpression (..))
import qualified Distribution.SPDX as SPDX
import Distribution.SPDX.License as SPDX
import Distribution.System
import Distribution.Types.CondTree as Cabal
import Distribution.Types.Dependency as Cabal
import Distribution.Types.ExeDependency as Cabal
import Distribution.Types.ExecutableScope as Cabal
import Distribution.Types.ForeignLib as Cabal
import Distribution.Types.ForeignLibOption as Cabal
import Distribution.Types.ForeignLibType as Cabal
import Distribution.Types.IncludeRenaming as Cabal
import Distribution.Types.LegacyExeDependency as Cabal
import Distribution.Types.LibraryVisibility as Cabal
import Distribution.Types.Mixin as Cabal
import Distribution.Types.PackageId as Cabal
import Distribution.Types.PackageName as Cabal
import Distribution.Types.PkgconfigDependency as Cabal
import Distribution.Types.PkgconfigName
import Distribution.Types.PkgconfigVersion
import Distribution.Types.PkgconfigVersionRange
import Distribution.Types.UnqualComponentName as Cabal
import Distribution.Types.Version as Cabal
import Distribution.Types.VersionRange as Cabal
import Distribution.Utils.ShortText as Cabal
import Distribution.Verbosity as Cabal
import Language.Haskell.Extension
import System.Environment
cabal2JSON :: IO ()
cabal2JSON = do
args <- getArgs
case args of
[] -> error "Please provide path to cabal file as CLI argument"
arg -> do
genericPackageDescription <- Cabal.readGenericPackageDescription Cabal.deafening (head arg)
SB8.putStrLn $ LB.toStrict $ encodeJSONViaCodec genericPackageDescription
instance HasCodec GenericPackageDescription where
codec =
object "GenericPackageDescription" $
GenericPackageDescription
<$> requiredField' "description" .= packageDescription
<*> optionalFieldWithOmittedDefault' "package-flags" [] .= genPackageFlags
<*> optionalField' "library" .= condLibrary
<*> optionalFieldWithOmittedDefaultWith' "sublibraries" unqualComponentNameCodec [] .= condSubLibraries
<*> optionalFieldWithOmittedDefaultWith' "foreign-libs" unqualComponentNameCodec [] .= condForeignLibs
<*> optionalFieldWithOmittedDefaultWith' "executables" unqualComponentNameCodec [] .= condExecutables
<*> optionalFieldWithOmittedDefaultWith' "test-suites" unqualComponentNameCodec [] .= condTestSuites
<*> optionalFieldWithOmittedDefaultWith' "benchmarks" unqualComponentNameCodec [] .= condBenchmarks
deriving via (Autodocodec GenericPackageDescription) instance (FromJSON GenericPackageDescription)
deriving via (Autodocodec GenericPackageDescription) instance (ToJSON GenericPackageDescription)
unqualComponentNameCodec :: HasCodec b => JSONCodec [(UnqualComponentName, b)]
unqualComponentNameCodec = mapInListForCodec mkUnqualComponentName unUnqualComponentName
instance HasCodec UnqualComponentName where
codec = dimapCodec mkUnqualComponentName unUnqualComponentName codec
mapInListForCodec ::
HasCodec b =>
(String -> a) ->
(a -> String) ->
JSONCodec [(a, b)]
mapInListForCodec fromText toText =
dimapCodec
(f . HM.toList)
(HM.fromList . g)
codec
where
f = map (first fromText)
g = map (first toText)
instance Hashable UnqualComponentName where
hashWithSalt s = hashWithSalt s . unUnqualComponentName
instance HasCodec VersionRange where
codec = bimapCodec f g codec
where
f = \s -> case eitherParsec s of
Left pe -> Left $ show pe
Right a -> Right a
g = prettyShow
instance HasCodec CompilerFlavor where
codec =
stringConstCodec
[ (GHC, "GHC"),
(GHCJS, "GHCJS"),
(NHC, "NHC"),
(YHC, "YHC"),
(HBC, "HBC"),
(Helium, "Helium"),
(JHC, "JHC"),
(LHC, "LHC"),
(UHC, "UHC"),
(Eta, "Eta")
]
instance HasCodec PackageDescription where
codec =
object "PackageDescription" $
PackageDescription
<$> requiredField' "spec-version" .= specVersionRaw
<*> requiredField' "package" .= package
<*> requiredField' "license" .= licenseRaw
<*> requiredField' "license-files" .= licenseFiles
<*> requiredField' "copyright" .= copyright
<*> requiredField' "maintainer" .= maintainer
<*> requiredField' "author" .= author
<*> requiredField' "stability" .= stability
<*> requiredField' "tested-with" .= testedWith
<*> requiredField' "homepage" .= homepage
<*> requiredField' "pkg-url" .= pkgUrl
<*> requiredField' "bug-reports" .= bugReports
<*> requiredField' "source-repos" .= sourceRepos
<*> requiredField' "synopsis" .= synopsis
<*> requiredField' "description" .= description
<*> requiredField' "category" .= category
<*> requiredField' "custom-fields" .= customFieldsPD
<*> requiredField' "build-type-raw" .= buildTypeRaw
<*> requiredField' "custom-setup" .= setupBuildInfo
<*> requiredField' "library" .= library
<*> requiredField' "sublibraries" .= subLibraries
<*> requiredField' "executables" .= executables
<*> requiredField' "foreign-libs" .= foreignLibs
<*> requiredField' "test-suites" .= testSuites
<*> requiredField' "benchmarks" .= benchmarks
<*> requiredField' "data-files" .= dataFiles
<*> requiredField' "data-dir" .= dataDir
<*> requiredField' "extra-source-files" .= extraSrcFiles
<*> requiredField' "extra-tmp-files" .= extraTmpFiles
<*> requiredField' "extra-doc-files" .= extraDocFiles
instance HasCodec (PerCompilerFlavor [String]) where
codec = dimapCodec (uncurry PerCompilerFlavor) (\(PerCompilerFlavor a b) -> (a, b)) codec
instance (HasCodec a) => HasCodec (a, a) where
codec = dimapCodec (\(a : [b]) -> (a, b)) (\(a, b) -> [a, b]) codec
instance HasCodec (CompilerFlavor, VersionRange) where
codec =
object "(CompilerFlavor, VersionRange)" $
(,)
<$> requiredField' "compiler" .= fst
<*> requiredField' "versionRange" .= snd
instance (HasCodec a) => HasCodec (a, a, a) where
codec = dimapCodec (\(a : b : [c]) -> (a, b, c)) (\(a, b, c) -> [a, b, c]) codec
instance HasCodec (Maybe String, String) where
codec =
dimapCodec
( \case
("", s) -> (Nothing, s)
(s1, s2) -> (Just s1, s2)
)
( \case
(Nothing, s) -> ("", s)
(Just s1, s2) -> (s1, s2)
)
codec
instance HasCodec PackageName where
codec = dimapCodec mkPackageName unPackageName codec
instance HasCodec PackageIdentifier where
codec =
object "PackgeIdentifier" $
PackageIdentifier
<$> requiredField' "name" .= pkgName
<*> requiredField' "version" .= pkgVersion
instance HasCodec RepoKind where
codec =
object "RepoKind" $
dimapCodec f g $
eitherCodec (pure RepoHead) $
eitherCodec (pure RepoThis) $
requiredField' "repo-kind"
where
f = \case
Left _ -> RepoHead
Right (Left _) -> RepoThis
Right (Right s) -> RepoKindUnknown s
g = \case
RepoHead -> Left ()
RepoThis -> Right $ Left ()
RepoKindUnknown s -> Right $ Right s
instance HasCodec RepoType where
-- TODO add OtherRepoType
codec =
stringConstCodec
[ (Darcs, "Darcs"),
(Git, "Git"),
(SVN, "SVN"),
(CVS, "CVS"),
(Mercurial, "Mercurial"),
(GnuArch, "GnuArch"),
(Bazaar, "Bazaar"),
(Monotone, "Monotone")
]
instance HasCodec Dependency where
codec =
object "Dependency" $
Dependency
<$> requiredField' "package-name" .= (\(Dependency name _ _) -> name)
<*> requiredField' "version-range" .= (\(Dependency _ version _) -> version)
<*> requiredField' "library" .= (\(Dependency _ _ lib) -> lib)
instance HasCodec SourceRepo where
codec =
object "SourceRepo" $
SourceRepo
<$> requiredField' "kind" .= repoKind
<*> requiredField' "type" .= repoType
<*> requiredField' "location" .= repoLocation
<*> requiredField' "module" .= repoModule
<*> requiredField' "branch" .= repoBranch
<*> requiredField' "tag" .= repoTag
<*> requiredField' "subdir" .= repoSubdir
instance HasCodec ShortText where
codec = dimapCodec toShortText fromShortText codec
instance HasCodec Cabal.License where
-- TODO add others
codec =
named "Cabal.License" $
stringConstCodec
[ (BSD2, "BSD2"),
(BSD3, "BSD3"),
(BSD4, "BSD4"),
(MIT, "MIT"),
(ISC, "ISC"),
(PublicDomain, "PublicDomain"),
(AllRightsReserved, "AllRightsReserved"),
(UnspecifiedLicense, "UnspecifiedLicense"),
(OtherLicense, "OtherLicense")
]
instance HasCodec SPDX.License where
codec =
named "SPDX.License" $
object "spdx-license" $
dimapCodec f g $
eitherCodec (pure NONE) $
requiredField' "license-expression"
where
f = \case
Left _ -> NONE
Right e -> License e
g = \case
NONE -> Left ("None" :: String)
License e -> Right e
instance HasCodec SPDX.LicenseExpression where
codec =
named "LicenseExpression" $
dimapCodec f g $
eitherCodec (object "ELicense" $ (,) <$> requiredField' "expression" .= fst <*> requiredField' "exception-id" .= snd) $
eitherCodec (object "EAnd" $ (,) <$> requiredField' "expression-1" .= fst <*> requiredField' "expression-2" .= snd) $
object "EOr" $ (,) <$> requiredField' "expression-11" .= fst <*> requiredField' "expression-22" .= snd
where
f = \case
Left (e, c) -> ELicense e c
Right (Left (exp1, exp2)) -> EAnd exp1 exp2
Right (Right (exp1, exp2)) -> EOr exp1 exp2
g = \case
ELicense e c -> Left (e, c)
EAnd exp1 exp2 -> Right $ Left (exp1, exp2)
EOr exp1 exp2 -> Right $ Right (exp1, exp2)
instance HasCodec SPDX.SimpleLicenseExpression where
codec =
object "SimpleLicenseExpression" $
dimapCodec f g $
eitherCodec (requiredField' "id") $
eitherCodec (requiredField' "id-plus") $
requiredField' "license-ref"
where
f = \case
Left i -> ELicenseId i
Right (Left i) -> ELicenseIdPlus i
Right (Right ref) -> ELicenseRef ref
g = \case
ELicenseId i -> Left i
ELicenseIdPlus i -> Right $ Left i
ELicenseRef ref -> Right $ Right ref
instance HasCodec SPDX.LicenseId where
codec = named "SPDX.LicenseId" shownBoundedEnumCodec
instance HasCodec SPDX.LicenseRef where
codec = dimapCodec f g codec
where
f = uncurry SPDX.mkLicenseRef'
g = \l -> (SPDX.licenseDocumentRef l, SPDX.licenseRef l)
instance HasCodec SPDX.LicenseExceptionId where
codec = shownBoundedEnumCodec
instance HasCodec BuildType where
codec = stringConstCodec [(Simple, "Simple"), (Configure, "Configure"), (Make, "Make"), (Custom, "Custom")]
instance HasCodec SetupBuildInfo where
codec =
object "SetupBuildInfo" $
SetupBuildInfo
<$> requiredField' "setup-depends" .= setupDepends
-- TODO: not needed
<*> requiredField' "__defaultSetupDepends" .= defaultSetupDepends
instance HasCodec Flag where
codec =
object "Flag" $
MkFlag
<$> requiredField' "name" .= flagName
<*> requiredField' "description" .= flagDescription
<*> requiredField' "default" .= flagDefault
<*> requiredField' "manual" .= flagManual
instance HasCodec FlagName where
codec = dimapCodec mkFlagName unFlagName codec
instance HasCodec a => HasCodec (CondTree ConfVar [Dependency] a) where
codec =
named "ConditionalTree" $
object "CondTree" $
CondNode
<$> requiredField' "condTreeData" .= condTreeData
<*> requiredField' "condTreeConstraints" .= condTreeConstraints
<*> requiredField' "condTreeComponents" .= condTreeComponents
instance (HasCodec a) => HasCodec (CondBranch ConfVar [Dependency] a) where
codec =
object "CondBranch" $
CondBranch
<$> requiredField' "condBranchCondition" .= condBranchCondition
<*> requiredField' "condBranchIfTrue" .= condBranchIfTrue
<*> optionalField' "condBranchIfFalse" .= condBranchIfFalse
instance HasCodec (Condition ConfVar) where
codec =
named "Condition" $
dimapCodec f g $
eitherCodec (object "var" $ requiredField' "v") $
eitherCodec (object "lit" $ requiredField' "bool") $
eitherCodec (object "cnot" $ requiredField' "cond") $
eitherCodec (object "cor" $ (,) <$> requiredField' "cond1" .= fst <*> requiredField' "cond2" .= snd) $
object "cand" $ (,) <$> requiredField' "cond12" .= fst <*> requiredField' "cond22" .= snd
where
f = \case
Left c -> Var c
Right (Left b) -> Lit b
Right (Right (Left cond)) -> CNot cond
Right (Right (Right (Left (cond1, cond2)))) -> COr cond1 cond2
Right (Right (Right (Right (cond1, cond2)))) -> CAnd cond1 cond2
g = \case
Var c -> Left c
Lit b -> Right $ Left b
CNot cond -> Right $ Right $ Left cond
COr cond1 cond2 -> Right $ Right $ Right $ Left (cond1, cond2)
CAnd cond1 cond2 -> Right $ Right $ Right $ Right (cond1, cond2)
instance HasCodec ConfVar where
codec =
object "ConfVar" $
dimapCodec f g $
eitherCodec (requiredField' "os") $
eitherCodec (requiredField' "arch") $
eitherCodec (requiredField' "flag") $
(,) <$> requiredField' "compiler" .= fst <*> requiredField' "version" .= snd
where
f = \case
Left o -> OS o
Right (Left a) -> Arch a
Right (Right (Left name)) -> Flag name
Right (Right (Right (compiler, version))) -> Impl compiler version
g = \case
OS o -> Left o
Arch a -> Right $ Left a
Flag name -> Right $ Right $ Left name
Impl compiler version -> Right $ Right $ Right (compiler, version)
instance HasCodec Arch where
-- TODO add OtherArch
codec =
stringConstCodec
[ (I386, "I386"),
(X86_64, "X86_64"),
(PPC, "PPC"),
(PPC64, "PPC64"),
(Sparc, "Sparc"),
(Arm, "Arm"),
(AArch64, "AArch64"),
(Mips, "Mips"),
(SH, "SH"),
(IA64, "IA64"),
(S390, "S390"),
(Alpha, "Alpha"),
(Hppa, "Hppa"),
(Rs6000, "Rs6000"),
(M68k, "M68k"),
(Vax, "Vax"),
(JavaScript, "JavaScript")
]
instance HasCodec OS where
-- TODO add OtherOS
codec =
stringConstCodec
[ (Linux, "Linux"),
(Windows, "Windows"),
(OSX, "OSX"),
(FreeBSD, "FreeBSD"),
(OpenBSD, "OpenBSD"),
(NetBSD, "NetBSD"),
(DragonFly, "DragonFly"),
(Solaris, "Solaris"),
(AIX, "AIX"),
(HPUX, "HPUX"),
(IRIX, "IRIX"),
(HaLVM, "HaLVM"),
(Hurd, "Hurd"),
(IOS, "IOS"),
(Android, "Android"),
(Ghcjs, "Ghcjs")
]
instance HasCodec Library where
codec =
object "Library" $
Library
<$> requiredField' "name" .= libName
<*> requiredField' "exposed-modules" .= exposedModules
<*> requiredField' "re-exported-modules" .= reexportedModules
<*> requiredField' "signatures" .= signatures
<*> requiredField' "exposed" .= libExposed
<*> requiredField' "visibility" .= libVisibility
<*> requiredField' "build-info" .= libBuildInfo
instance HasCodec LibraryName where
codec =
object "LibraryName" $
dimapCodec f g $
eitherCodec (pure LMainLibName) $
requiredField' "sub-lib-name"
where
f = \case
Left _ -> LMainLibName
Right s -> LSubLibName s
g = \case
LMainLibName -> Left ()
LSubLibName s -> Right s
instance HasCodec ModuleName where
codec = dimapCodec fromComponents components codec
instance HasCodec ModuleReexport where
codec =
object "ModuleReexport" $
ModuleReexport
<$> requiredField' "moduleReexportOriginalPackage" .= moduleReexportOriginalPackage
<*> requiredField' "moduleReexportOriginalName" .= moduleReexportOriginalName
<*> requiredField' "moduleReexportName" .= moduleReexportName
instance HasCodec LibraryVisibility where
codec = stringConstCodec [(LibraryVisibilityPublic, "LibraryVisibilityPublic"), (LibraryVisibilityPrivate, "LibraryVisibilityPrivate")]
instance HasCodec ForeignLib where
codec =
object "ForeignLib" $
ForeignLib
<$> requiredField' "name" .= foreignLibName
<*> requiredField' "type" .= foreignLibType
<*> requiredField' "options" .= foreignLibOptions
<*> requiredField' "build-info" .= foreignLibBuildInfo
<*> requiredField' "version-info" .= foreignLibVersionInfo
<*> requiredField' "linux-version" .= foreignLibVersionLinux
<*> requiredField' "mod-def-files" .= foreignLibModDefFile
instance HasCodec ForeignLibType where
codec = stringConstCodec [(ForeignLibNativeShared, "ForeignLibNativeShared"), (ForeignLibNativeStatic, "ForeignLibNativeStatic"), (ForeignLibTypeUnknown, "ForeignLibTypeUnknown")]
instance HasCodec ForeignLibOption where
codec = literalTextValueCodec ForeignLibStandalone "ForeignLibStandalone"
instance HasCodec LibVersionInfo where
codec = dimapCodec mkLibVersionInfo libVersionInfoCRA codec
instance HasCodec Version where
codec = dimapCodec mkVersion versionNumbers codec
instance HasCodec Executable where
codec =
object "Executable" $
Executable
<$> requiredField' "name" .= exeName
<*> requiredField' "module-path" .= modulePath
<*> requiredField' "scope" .= exeScope
<*> requiredField' "build-info" .= buildInfo
instance HasCodec ExecutableScope where
codec =
stringConstCodec $
NE.fromList
[ (ExecutablePublic, "public"),
(ExecutablePrivate, "private")
]
instance HasCodec TestSuite where
codec =
object "TestSuite" $
TestSuite
<$> requiredField' "name" .= testName
<*> requiredField' "interface" .= testInterface
<*> requiredField' "build-info" .= testBuildInfo
instance HasCodec TestSuiteInterface where
codec =
object "TestSuiteInterface" $
dimapCodec f g $
eitherCodec ((,) <$> requiredField' "version" .= fst <*> requiredField' "filepath" .= snd) $
eitherCodec ((,) <$> requiredField' "version" .= fst <*> requiredField' "module-name" .= snd) $
requiredField' "type"
where
f = \case
Left (v, fp) -> TestSuiteExeV10 v fp
Right (Left (v, mn)) -> TestSuiteLibV09 v mn
Right (Right tt) -> TestSuiteUnsupported tt
g = \case
TestSuiteExeV10 v fp -> Left (v, fp)
TestSuiteLibV09 v mn -> Right $ Left (v, mn)
TestSuiteUnsupported tt -> Right $ Right tt
instance HasCodec TestType where
codec =
object "TestType" $
dimapCodec f g $
eitherCodec (requiredField' "version") $
eitherCodec (requiredField' "version") $
(,) <$> requiredField' "name" .= fst <*> requiredField' "version" .= snd
where
f = \case
Left v -> TestTypeExe v
Right (Left v) -> TestTypeLib v
Right (Right (s, v)) -> TestTypeUnknown s v
g = \case
TestTypeExe v -> Left v
TestTypeLib v -> Right $ Left v
TestTypeUnknown s v -> Right $ Right (s, v)
instance HasCodec Benchmark where
codec =
object "Benchmark" $
Benchmark
<$> requiredField' "name" .= benchmarkName
<*> requiredField' "interface" .= benchmarkInterface
<*> requiredField' "build-info" .= benchmarkBuildInfo
instance HasCodec BenchmarkType where
codec =
object "BenchmarkType" $
dimapCodec f g $
eitherCodec (requiredField' "benchmark-type") $
(,)
<$> requiredField' "type" .= fst
<*> requiredField' "version" .= snd
where
f = \case
Left v -> BenchmarkTypeExe v
Right (s, v) -> BenchmarkTypeUnknown s v
g = \case
BenchmarkTypeExe v -> Left v
BenchmarkTypeUnknown s v -> Right (s, v)
instance HasCodec BenchmarkInterface where
codec =
dimapCodec f g $
eitherCodec
( object "BenchmarkExeV10" $
(,)
<$> requiredField' "version" .= fst
<*> requiredField' "filepath" .= snd
)
$ object "BenchmarkUnsupported" $ requiredField' "benchmark-type"
where
f = \case
Left (version, file) -> BenchmarkExeV10 version file
Right t -> BenchmarkUnsupported t
g = \case
BenchmarkExeV10 version file -> Left (version, file)
BenchmarkUnsupported t -> Right t
instance HasCodec ModuleRenaming where
codec =
object "ModuleRenaming" $
dimapCodec f g $
eitherCodec (pure DefaultRenaming) $
eitherCodec (requiredField' "name") (requiredField' "name")
where
f = \case
Left _ -> DefaultRenaming
Right (Left m) -> ModuleRenaming m
Right (Right m) -> HidingRenaming m
g = \case
DefaultRenaming -> Left ()
ModuleRenaming m -> Right $ Left m
HidingRenaming m -> Right $ Right m
instance HasCodec IncludeRenaming where
codec =
object "IncludeRenaming" $
IncludeRenaming
<$> requiredField' "includeProvidesRn" .= includeProvidesRn
<*> requiredField' "includeRequiresRn" .= includeRequiresRn
instance HasCodec Mixin where
codec =
object "Mixin" $
Mixin
<$> requiredField' "package-name" .= mixinPackageName
<*> requiredField' "include-renaming" .= mixinIncludeRenaming
instance HasCodec LegacyExeDependency where
codec =
object "LegacyExeDependency" $
LegacyExeDependency
<$> requiredField' "package-name" .= (\(LegacyExeDependency s _) -> s)
<*> requiredField' "include-renaming" .= (\(LegacyExeDependency _ vr) -> vr)
instance HasCodec ExeDependency where
codec =
object "ExeDependency" $
ExeDependency
<$> requiredField' "package-name" .= (\(ExeDependency a _ _) -> a)
<*> requiredField' "executable-component-name" .= (\(ExeDependency _ b _) -> b)
<*> requiredField' "version-range" .= (\(ExeDependency _ _ c) -> c)
instance HasCodec PkgconfigDependency where
codec =
object "PkgconfigDependency" $
PkgconfigDependency
<$> requiredField' "pkgconfigName" .= (\(PkgconfigDependency name _) -> name)
<*> requiredField' "pkgconfigVersionRange" .= (\(PkgconfigDependency _ version) -> version)
instance HasCodec PkgconfigName where
codec = dimapCodec mkPkgconfigName unPkgconfigName codec
instance HasCodec PkgconfigVersionRange where
codec = bimapCodec f g codec
where
f = \s -> case eitherParsec s of
Left pe -> Left $ show pe
Right a -> Right a
g = prettyShow
instance HasCodec PkgconfigVersion where
codec =
bimapCodec
(Right . PkgconfigVersion . encodeUtf8)
( \(PkgconfigVersion v) -> case decodeUtf8' v of
Left ex -> T.pack $ show ex
Right txt -> txt
)
codec
instance HasCodec Language where
codec =
dimapCodec f g $
eitherCodec (literalTextValueCodec Haskell98 "Haskell98") $
eitherCodec
(literalTextValueCodec Haskell2010 "Haskell2010")
codec
where
f = \case
Left l -> l
Right (Left l) -> l
Right (Right s) -> UnknownLanguage s
g = \case
Haskell98 -> Left Haskell98
Haskell2010 -> Right $ Left Haskell2010
UnknownLanguage s -> Right $ Right s
instance HasCodec Extension where
codec =
named "Extension" $
object "Extension" $
dimapCodec f g $
eitherCodec (requiredField' "enable-extension") $
eitherCodec
(requiredField' "disable-extension")
(requiredField' "unknown-extension")
where
f = \case
Left e -> EnableExtension e
Right (Left e) -> DisableExtension e
Right (Right s) -> UnknownExtension s
g = \case
EnableExtension e -> Left e
DisableExtension e -> Right $ Left e
UnknownExtension e -> Right $ Right e
instance HasCodec KnownExtension where
codec = named "KnownExtension" shownBoundedEnumCodec
instance HasCodec BuildInfo where
codec =
object "BuildInfo" $
BuildInfo
<$> requiredField' "buildable" .= buildable
<*> requiredField' "buildTools" .= buildTools
<*> requiredField' "buildToolDepends" .= buildToolDepends
<*> requiredField' "cppOptions" .= cppOptions
<*> requiredField' "asmOptions" .= asmOptions
<*> requiredField' "cmmOptions" .= cmmOptions
<*> requiredField' "ccOptions" .= ccOptions
<*> requiredField' "cxxOptions" .= cxxOptions
<*> requiredField' "ldOptions" .= ldOptions
<*> requiredField' "pkgconfigDepends" .= pkgconfigDepends
<*> requiredField' "frameworks" .= frameworks
<*> requiredField' "extraFrameworkDirs" .= extraFrameworkDirs
<*> requiredField' "asmSources" .= asmSources
<*> requiredField' "cmmSources" .= cmmSources
<*> requiredField' "cSources" .= cSources
<*> requiredField' "cxxSources" .= cxxSources
<*> requiredField' "jsSources" .= jsSources
<*> requiredField' "hsSourceDirs" .= hsSourceDirs
<*> requiredField' "otherModules" .= otherModules
<*> requiredField' "virtualModules" .= virtualModules
<*> requiredField' "autogenModules" .= autogenModules
<*> requiredField' "defaultLanguage" .= defaultLanguage
<*> requiredField' "otherLanguages" .= otherLanguages
<*> requiredField' "defaultExtensions" .= defaultExtensions
<*> requiredField' "otherExtensions" .= otherExtensions
<*> requiredField' "oldExtensions" .= oldExtensions
<*> requiredField' "extraLibs" .= extraLibs
<*> requiredField' "extraGHCiLibs" .= extraGHCiLibs
<*> requiredField' "extraBundledLibs" .= extraBundledLibs
<*> requiredField' "extraLibFlavours" .= extraLibFlavours
<*> requiredField' "extraDynLibFlavours" .= extraDynLibFlavours
<*> requiredField' "extraLibDirs" .= extraLibDirs
<*> requiredField' "includeDirs" .= includeDirs
<*> requiredField' "includes" .= includes
<*> requiredField' "autogenIncludes" .= autogenIncludes
<*> requiredField' "installIncludes" .= installIncludes
<*> requiredField' "options" .= options
<*> requiredField' "profOptions" .= profOptions
<*> requiredField' "sharedOptions" .= sharedOptions
<*> requiredField' "staticOptions" .= staticOptions
<*> requiredField' "customFieldsBI" .= customFieldsBI
<*> requiredField' "targetBuildDepends" .= targetBuildDepends
<*> requiredField' "mixins" .= mixins