dzen-dhall-1.0.0: src/DzenDhall/Config.hs
{-# LANGUAGE TemplateHaskell #-}
-- | Data types for marshalling dhall configs into Haskell.
module DzenDhall.Config where
import qualified Data.HashMap.Strict as H
import Data.Hashable
import Data.Text (Text)
import Dhall
import Lens.Micro.TH
import Lens.Micro (Lens', _1)
import DzenDhall.Extra
type AutomatonState = Text
stateType :: Type AutomatonState
stateType = union $ constructor "State" strictText
type AutomatonAddress = Text
automatonAddressType :: Type AutomatonAddress
automatonAddressType = union $ constructor "Address" strictText
type Scope = Text
type VariableName = Text
type Value = Text
type ImageContents = Text
type ImageId = Text
data Marquee
= Marquee
{ _mqFramesPerChar :: Int
, _mqWidth :: Int
, _mqShouldWrap :: Bool
}
deriving (Show, Eq, Generic)
makeLenses ''Marquee
marqueeType :: Type Marquee
marqueeType = record $
Marquee <$> field "framesPerCharacter" (positive . fromIntegral <$> natural)
<*> field "width" (nonNegative . fromIntegral <$> natural)
<*> field "shouldWrap" bool
data Direction
= DLeft | DRight
deriving (Show, Eq, Generic)
directionType :: Type Direction
directionType = union
$ (DLeft <$ constructor "Left" unit)
<> (DRight <$ constructor "Right" unit)
data VerticalDirection
= VUp | VDown
deriving (Show, Eq, Generic)
verticalDirectionType :: Type VerticalDirection
verticalDirectionType = union
$ (VUp <$ constructor "Up" unit)
<> (VDown <$ constructor "Down" unit)
data Assertion
= BinaryInPath Text
| SuccessfulExit Text
deriving (Show, Eq, Generic)
assertionType :: Type Assertion
assertionType = union
$ (BinaryInPath <$> constructor "BinaryInPath" strictText)
<> (SuccessfulExit <$> constructor "SuccessfulExit" strictText)
data Check
= Check { _chMessage :: Text
, _chAssertion :: Assertion
}
deriving (Show, Eq, Generic)
makeLenses ''Check
checkType :: Type Check
checkType = record $
Check <$> field "message" strictText
<*> field "assertion" assertionType
data Button
= MouseLeft
| MouseMiddle
| MouseRight
| MouseScrollUp
| MouseScrollDown
| MouseScrollLeft
| MouseScrollRight
deriving (Show, Eq, Ord, Generic)
instance Hashable Button
buttonType :: Type Button
buttonType = union
$ (MouseLeft <$ constructor "Left" unit)
<> (MouseMiddle <$ constructor "Middle" unit)
<> (MouseRight <$ constructor "Right" unit)
<> (MouseScrollUp <$ constructor "ScrollUp" unit)
<> (MouseScrollDown <$ constructor "ScrollDown" unit)
<> (MouseScrollLeft <$ constructor "ScrollLeft" unit)
<> (MouseScrollRight <$ constructor "ScrollRight" unit)
newtype Event
= Event Text
deriving (Show, Eq, Ord, Generic)
instance Hashable Event
eventType :: Type Event
eventType = union $ (Event <$> constructor "Event" strictText)
data Fade
= Fade
{ _fadeDirection :: VerticalDirection
, _fadeFrameCount :: Int
, _fadePixelHeight :: Int
}
deriving (Show, Eq, Generic)
makeLenses ''Fade
fadeType :: Type Fade
fadeType = record $
Fade <$> field "direction" verticalDirectionType
<*> field "frameCount" (fromIntegral <$> natural)
<*> field "height" (fromIntegral <$> natural)
data Slider
= Slider
{ _fadeIn :: Fade
, _fadeOut :: Fade
, _sliderDelay :: Int
}
deriving (Show, Eq, Generic)
makeLenses ''Slider
sliderType :: Type Slider
sliderType = record $
Slider <$> field "fadeIn" fadeType
<*> field "fadeOut" fadeType
<*> field "delay" (fromIntegral <$> natural)
data Hook
= Hook
{ _hookCommand :: [Text]
, _hookInput :: Text
}
deriving (Show, Eq, Generic)
makeLenses ''Hook
hookType :: Type Hook
hookType = record $
Hook <$> field "command" (list strictText)
<*> field "input" strictText
newtype StateTransitionTable
= STT { unSTT :: H.HashMap (Scope, Event, AutomatonState) (AutomatonState, [Hook])
}
deriving (Show, Eq, Generic)
stateTransitionTableType :: Type StateTransitionTable
stateTransitionTableType = STT . H.fromList . concatMap collect <$> list
( record
( pack5 <$> field "events" (list eventType)
<*> field "from" (list stateType)
<*> field "to" stateType
<*> field "hooks" (list hookType)
)
)
where
pack5 events froms to hooks = (events, froms, to, hooks)
collect (events, froms, to, hooks) =
[ (("", event, from), (to, hooks))
-- ^ scope is left uninitialized. It will be added later
| event <- events
, from <- froms
]
_scope :: Lens' (Scope, Event, AutomatonState) Scope
_scope = _1
newtype Color = Color Text
deriving (Show, Eq, Generic)
colorType :: Type Color
colorType = Color <$> strictText
data AbsolutePosition
= AbsolutePosition { _apX :: Int, _apY :: Int }
deriving (Show, Eq, Generic)
makeLenses ''AbsolutePosition
absolutePositionType :: Type AbsolutePosition
absolutePositionType = record $
AbsolutePosition <$> field "x" (fromIntegral <$> integer)
<*> field "y" (fromIntegral <$> integer)
{- | Specify position that will be passed to @^p()@. -}
data Position =
-- | @^p(+-X;+-Y)@ - move X pixels to the right or left and Y pixels up or down of the current
-- position (on the X and Y axis).
XY (Int, Int) |
-- | @^p()@ - Reset the Y position to its default.
P_RESET_Y |
-- | @_LOCK_X@ - Lock the current X position, useful if you want to align things vertically
P_LOCK_X |
-- | @_UNLOCK_X@ - Unlock the X position
P_UNLOCK_X |
-- | @_LEFT@ - Move current x-position to the left edge
P_LEFT |
-- | @_RIGHT@ - Move current x-position to the right edge
P_RIGHT |
-- | @_TOP@ - Move current y-position to the top edge
P_TOP |
-- | @_CENTER@ - Move current x-position to the center of the window
P_CENTER |
-- | @_BOTTOM@ - Move current y-position to the bottom edge
P_BOTTOM
deriving (Show, Eq, Generic)
positionType :: Type Position
positionType = union
$ (XY <$> constructor "XY" xy)
<> (P_RESET_Y <$ constructor "_RESET_Y" unit)
<> (P_LOCK_X <$ constructor "_LOCK_X" unit)
<> (P_UNLOCK_X <$ constructor "_UNLOCK_X" unit)
<> (P_LEFT <$ constructor "_LEFT" unit)
<> (P_RIGHT <$ constructor "_RIGHT" unit)
<> (P_TOP <$ constructor "_TOP" unit)
<> (P_CENTER <$ constructor "_CENTER" unit)
<> (P_BOTTOM <$ constructor "_BOTTOM" unit)
where
xy = record ((,) <$> (fromIntegral <$> field "x" integer)
<*> (fromIntegral <$> field "y" integer))
data ClickableArea
= ClickableArea { _caButton :: Button
, _caCommand :: Text
}
deriving (Show, Eq, Generic)
makeLenses ''ClickableArea
clickableAreaType :: Type ClickableArea
clickableAreaType = record $
ClickableArea <$> field "button" buttonType
<*> field "command" strictText
data Padding
= PLeft
| PRight
| PSides
deriving (Show, Eq, Generic)
paddingType :: Type Padding
paddingType = union
$ (PLeft <$ constructor "Left" unit)
<> (PRight <$ constructor "Right" unit)
<> (PSides <$ constructor "Sides" unit)
data OpeningTag
= OMarquee Marquee
| OSlider Slider
| OFG Color
| OBG Color
| OP Position
| OPA AbsolutePosition
| OCA ClickableArea
| OIB
| OPadding Int Padding
| OTrim Int Direction
| OAutomaton AutomatonAddress StateTransitionTable
| OStateMapKey Text
| OScope
deriving (Show, Eq, Generic)
openingTagType :: Type OpeningTag
openingTagType = union
$ (OMarquee <$> constructor "Marquee" marqueeType)
<> (OSlider <$> constructor "Slider" sliderType)
<> (OFG <$> constructor "FG" colorType)
<> (OBG <$> constructor "BG" colorType)
<> (OP <$> constructor "P" positionType)
<> (OPA <$> constructor "PA" absolutePositionType)
<> (OCA <$> constructor "CA" clickableAreaType)
<> (OIB <$ constructor "IB" unit)
<> (uncurry OPadding <$> constructor "Padding"
( record $ (,) <$> field "width" (fromIntegral <$> natural)
<*> field "padding" paddingType
)
)
<> (uncurry OTrim <$> constructor "Trim"
( record $ (,) <$> field "width" (fromIntegral <$> natural)
<*> field "direction" directionType
)
)
<> (uncurry OAutomaton <$> constructor "Automaton"
( record $ (,) <$> field "address" automatonAddressType
<*> field "stt" stateTransitionTableType
)
)
<> (OStateMapKey <$> constructor "StateMapKey" stateType)
<> (OScope <$ constructor "Scope" unit)
data BarSettings
= BarSettings
{ _bsMonitor :: Int
-- ^ Xinerama monitor number
, _bsExtraArgs :: [String]
-- ^ Extra args to pass to dzen binary
, _bsUpdateInterval :: Int
-- ^ In microseconds
, _bsFont :: Maybe String
-- ^ Font in XLFD format
, _bsFontWidth :: Int
}
deriving (Show, Eq, Generic)
makeLenses ''BarSettings
barSettingsType :: Type BarSettings
barSettingsType = record $
BarSettings <$> field "monitor" (fromIntegral <$> natural)
<*> field "extraArgs" (list string)
<*> field "updateInterval" ((* 1000) . fromIntegral <$> natural)
<*> field "font" (Dhall.maybe string)
<*> field "fontWidth" (fromIntegral <$> natural)
data ShapeSize
= ShapeSize { _shapeSizeW :: Int, _shapeSizeH :: Int }
deriving (Show, Eq, Generic)
makeLenses ''ShapeSize
shapeSizeType :: Type ShapeSize
shapeSizeType = record $
ShapeSize <$> field "w" (fromIntegral <$> natural)
<*> field "h" (fromIntegral <$> natural)
data Variable
= Variable { _varName :: Text
, _varValue :: Text
}
deriving (Show, Eq, Generic)
makeLenses ''Variable
variableType :: Type Variable
variableType = record $
Variable <$> field "name" strictText
<*> field "value" strictText
data Token
= TokOpen OpeningTag
| TokClose
| TokSeparator
| TokTxt Text
| TokSource Source
| TokMarkup Text
| TokI Text
| TokR ShapeSize
| TokRO ShapeSize
| TokC Int
| TokCO Int
| TokCheck Check
| TokDefine Variable
deriving (Show, Eq, Generic)
tokenType :: Type Token
tokenType = union
$ (TokOpen <$> constructor "Open" openingTagType)
<> (TokClose <$ constructor "Close" unit)
<> (TokSeparator <$ constructor "Separator" unit)
<> (TokTxt <$> constructor "Txt" strictText)
<> (TokSource <$> constructor "Source" sourceSettingsType)
<> (TokMarkup <$> constructor "Markup" strictText)
<> (TokI <$> constructor "I" strictText)
<> (TokR <$> constructor "R" shapeSizeType)
<> (TokRO <$> constructor "RO" shapeSizeType)
<> (TokC <$> constructor "C" (fromIntegral <$> natural))
<> (TokCO <$> constructor "CO" (fromIntegral <$> natural))
<> (TokCheck <$> constructor "Check" checkType)
<> (TokDefine <$> constructor "Define" variableType)
stateMapType :: Type (H.HashMap Text [Token])
stateMapType = H.fromList <$>
list (record $
(,) <$> field "state" strictText
<*> field "bar" (list tokenType))
data Source
= Source
{ updateInterval :: Maybe Int
-- ^ In microseconds
, command :: [String]
, input :: Text
, escape :: Bool
} deriving (Show, Eq, Generic)
instance Hashable Source
sourceSettingsType :: Type Source
sourceSettingsType = record $
Source <$> field "updateInterval" (Dhall.maybe $ (* 1000) . fromIntegral <$> natural)
<*> field "command" (list string)
<*> field "input" strictText
<*> field "escape" bool
data Configuration = Configuration
{ _cfgBarTokens :: [Token]
, _cfgBarSettings :: BarSettings
}
deriving (Show, Eq, Generic)
makeLenses ''Configuration
configurationType :: Type Configuration
configurationType = record $
Configuration <$> field "bar" (list tokenType)
<*> field "settings" barSettingsType
data PluginMeta = PluginMeta
{ _pmName :: Text
, _pmAuthor :: Text
, _pmEmail :: Maybe Text
, _pmHomePage :: Maybe Text
, _pmUpstream :: Maybe Text
, _pmDescription :: Text
, _pmUsage :: Text
, _pmApiVersion :: Int
}
deriving (Show, Eq, Generic)
makeLenses ''PluginMeta
pluginMetaType :: Type PluginMeta
pluginMetaType = record $
PluginMeta <$> field "name" strictText
<*> field "author" strictText
<*> field "email" (Dhall.maybe strictText)
<*> field "homepage" (Dhall.maybe strictText)
<*> field "upstream" (Dhall.maybe strictText)
<*> field "description" strictText
<*> field "usage" strictText
<*> field "apiVersion" (fromIntegral <$> natural)