summaryrefslogtreecommitdiff
path: root/lib/Badges.hs
blob: c1a17b307e0209c362b1827ba8e48baf39a06a8f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
{-# LANGUAGE DeriveAnyClass             #-}
{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE DerivingStrategies         #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE RecordWildCards            #-}

-- | module defining Badge types and utility functions
module Badges where

import           Control.DeepSeq (NFData)
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
   }
  deriving (Ord, Eq, Generic, Show, NFData)

newtype BadgeToken = BadgeToken Text
  deriving newtype (Eq, Ord, Show, NFData)

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)
  then Just (BadgeToken text)
  else Nothing

data Badge = Badge BadgeToken BadgeArea
  deriving (Ord, Eq, Generic, Show, NFData)

instance ToJSON Badge where
  toJSON (Badge token area) = A.object $ case area of
         BadgePoint x y -> [ "x" .= x
                           , "y" .= y
                           , "token" .= token
                           , "type" .= A.String "point"
                           ]
         BadgeRect {..} -> [ "x" .= areaX
                           , "y" .= areaY
                           , "token" .= token
                           , "width" .= areaWidth
                           , "height" .= areaHeight
                           , "type" .= A.String "rectangle"
                           ]