summaryrefslogtreecommitdiff
path: root/lib/Badges.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Badges.hs')
-rw-r--r--lib/Badges.hs70
1 files changed, 70 insertions, 0 deletions
diff --git a/lib/Badges.hs b/lib/Badges.hs
new file mode 100644
index 0000000..0369334
--- /dev/null
+++ b/lib/Badges.hs
@@ -0,0 +1,70 @@
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+
+-- | module defining Badge types and utility functions
+module Badges where
+
+import Data.Aeson (Options (fieldLabelModifier, sumEncoding),
+ SumEncoding (UntaggedValue), ToJSON (toJSON),
+ defaultOptions, genericToJSON, (.=))
+import qualified Data.Aeson as A
+import Data.Char (toLower)
+import Data.Text (Text)
+import GHC.Generics (Generic)
+import Text.Regex.TDFA ((=~))
+
+
+data BadgeArea =
+ BadgePoint
+ { areaX :: Double
+ , areaY :: Double
+ }
+ | BadgeRect
+ { areaX :: Double
+ , areaY :: Double
+ , areaWidth :: Double
+ , areaHeight :: Double
+ , areaIsEllipse :: Bool
+ }
+ deriving (Ord, Eq, Generic, Show)
+
+newtype BadgeToken = BadgeToken Text
+ deriving (Eq, Ord, Show)
+
+instance ToJSON BadgeArea where
+ toJSON = genericToJSON defaultOptions
+ { fieldLabelModifier = drop 4 . map toLower
+ , sumEncoding = UntaggedValue }
+
+instance ToJSON BadgeToken where
+ toJSON (BadgeToken text) = toJSON text
+
+parseToken :: Text -> Maybe BadgeToken
+parseToken text = if text =~ ("^[a-zA-Z0-9]{50}$" :: Text) -- TODO: add character limit
+ then Just (BadgeToken text)
+ else Nothing
+
+data Badge = Badge BadgeToken BadgeArea
+ deriving (Ord, Eq, Generic, Show)
+
+badgeJsonArray :: A.KeyValue a => Badge -> [a]
+badgeJsonArray (Badge token area) =
+ [ "token" .= token ] <> areaObject
+ where areaObject = case area of
+ BadgePoint x y -> [ "x" .= x
+ , "y" .= y
+ , "type" .= A.String "point"
+ ]
+ BadgeRect {..} -> [ "x" .= areaX
+ , "y" .= areaY
+ , "width" .= areaWidth
+ , "height" .= areaHeight
+ , "type" .= if areaIsEllipse
+ then A.String "ellipse"
+ else A.String "rectangle"
+ ]
+
+badgeJson :: FilePath -> Badge -> A.Value
+badgeJson mappath badge = A.object (badgeJsonArray badge <> [ "map" .= mappath ])