108 lines
3.0 KiB
Haskell
108 lines
3.0 KiB
Haskell
{-# OPTIONS_GHC -Wno-orphans #-}
|
|
{-# LANGUAGE CPP #-}
|
|
{-# LANGUAGE DeriveDataTypeable #-}
|
|
{-# LANGUAGE DeriveLift #-}
|
|
{-# LANGUAGE FlexibleInstances #-}
|
|
{-# LANGUAGE StandaloneDeriving #-}
|
|
{-# LANGUAGE TemplateHaskell #-}
|
|
|
|
|
|
{-|
|
|
Module : GHCup.Utils.Version.QQ
|
|
Description : Version quasi-quoters
|
|
Copyright : (c) Julian Ospald, 2020
|
|
License : LGPL-3.0
|
|
Maintainer : hasufell@hasufell.de
|
|
Stability : experimental
|
|
Portability : portable
|
|
-}
|
|
module GHCup.Utils.Version.QQ where
|
|
|
|
import Data.Data
|
|
import Data.Text ( Text )
|
|
import Data.Versions
|
|
#if !MIN_VERSION_base(4,13,0)
|
|
import GHC.Base
|
|
#endif
|
|
import Language.Haskell.TH
|
|
import Language.Haskell.TH.Quote ( QuasiQuoter(..) )
|
|
import Language.Haskell.TH.Syntax ( Lift
|
|
, dataToExpQ
|
|
)
|
|
import qualified Data.Text as T
|
|
import qualified Language.Haskell.TH.Syntax as TH
|
|
|
|
|
|
|
|
deriving instance Data Versioning
|
|
deriving instance Lift Versioning
|
|
deriving instance Data Version
|
|
deriving instance Lift Version
|
|
deriving instance Data SemVer
|
|
deriving instance Lift SemVer
|
|
deriving instance Data Mess
|
|
deriving instance Lift Mess
|
|
deriving instance Data MChunk
|
|
deriving instance Lift MChunk
|
|
deriving instance Data PVP
|
|
deriving instance Lift PVP
|
|
deriving instance Lift VSep
|
|
deriving instance Data VSep
|
|
deriving instance Lift VUnit
|
|
deriving instance Data VUnit
|
|
|
|
#if !MIN_VERSION_base(4,13,0)
|
|
deriving instance Lift (NonEmpty Word)
|
|
deriving instance Lift (NonEmpty VChunk)
|
|
deriving instance Lift (NonEmpty MChunk)
|
|
deriving instance Lift (NonEmpty VUnit)
|
|
#endif
|
|
|
|
qq :: (Text -> Q Exp) -> QuasiQuoter
|
|
qq quoteExp' = QuasiQuoter
|
|
{ quoteExp = \s -> quoteExp' . T.pack $ s
|
|
, quotePat = \_ ->
|
|
fail "illegal QuasiQuote (allowed as expression only, used as a pattern)"
|
|
, quoteType = \_ ->
|
|
fail "illegal QuasiQuote (allowed as expression only, used as a type)"
|
|
, quoteDec = \_ -> fail
|
|
"illegal QuasiQuote (allowed as expression only, used as a declaration)"
|
|
}
|
|
|
|
vver :: QuasiQuoter
|
|
vver = qq mkV
|
|
where
|
|
mkV :: Text -> Q Exp
|
|
mkV = either (fail . show) liftDataWithText . version
|
|
|
|
mver :: QuasiQuoter
|
|
mver = qq mkV
|
|
where
|
|
mkV :: Text -> Q Exp
|
|
mkV = either (fail . show) liftDataWithText . mess
|
|
|
|
sver :: QuasiQuoter
|
|
sver = qq mkV
|
|
where
|
|
mkV :: Text -> Q Exp
|
|
mkV = either (fail . show) liftDataWithText . semver
|
|
|
|
vers :: QuasiQuoter
|
|
vers = qq mkV
|
|
where
|
|
mkV :: Text -> Q Exp
|
|
mkV = either (fail . show) liftDataWithText . versioning
|
|
|
|
pver :: QuasiQuoter
|
|
pver = qq mkV
|
|
where
|
|
mkV :: Text -> Q Exp
|
|
mkV = either (fail . show) liftDataWithText . pvp
|
|
|
|
-- https://stackoverflow.com/questions/38143464/cant-find-inerface-file-declaration-for-variable
|
|
liftText :: T.Text -> Q Exp
|
|
liftText txt = AppE (VarE 'T.pack) <$> TH.lift (T.unpack txt)
|
|
|
|
liftDataWithText :: Data a => a -> Q Exp
|
|
liftDataWithText = dataToExpQ (fmap liftText . cast)
|