module Github.PostReceive.Types
( Payload (..)
, Commit (..)
, Repository (..)
, User (..)
, EmailAddress
) where
import Control.Applicative ((<$>), (<*>), pure)
import Data.Aeson (Value (..), FromJSON (..), (.:), (.:?))
import qualified Data.ByteString.Char8 as B
import Data.Text (Text)
import qualified Data.Text as T
import Data.Typeable (Typeable)
import Text.Email.Validate (EmailAddress, emailAddress)
data Payload = Payload
{ payloadRef :: Text
, payloadAfter :: Text
, payloadBefore :: Text
, payloadCreated :: Bool
, payloadDeleted :: Bool
, payloadForced :: Bool
, payloadCompare :: Text
, payloadCommits :: [Commit]
, payloadHeadCommit :: Commit
, payloadRepository :: Repository
, payloadPusher :: User
} deriving (Show, Eq, Typeable)
instance FromJSON Payload where
parseJSON (Object o) = Payload
<$> o .: "ref"
<*> o .: "after"
<*> o .: "before"
<*> o .: "created"
<*> o .: "deleted"
<*> o .: "forced"
<*> o .: "compare"
<*> o .: "commits"
<*> o .: "head_commit"
<*> o .: "repository"
<*> o .: "pusher"
parseJSON _ = fail "Payload must be an object"
data Commit = Commit
{ commitId :: Text
, commitDistinct :: Bool
, commitMessage :: Text
, commitTimestamp :: Text
, commitUrl :: Text
, commitAuthor :: User
, commitCommitter :: User
, commitAdded :: [FilePath]
, commitRemoved :: [FilePath]
, commitModified :: [FilePath]
} deriving (Show, Eq, Typeable)
instance FromJSON Commit where
parseJSON (Object o) = Commit
<$> o .: "id"
<*> o .: "distinct"
<*> o .: "message"
<*> o .: "timestamp"
<*> o .: "url"
<*> o .: "author"
<*> o .: "committer"
<*> o .: "added"
<*> o .: "removed"
<*> o .: "modified"
parseJSON _ = fail "Commit must be an object"
data Repository = Repository
{ repoId :: Int
, repoName :: Text
, repoUrl :: Text
, repoDescription :: Text
, repoHomepage :: Maybe Text
, repoWatchers :: Int
, repoStargazers :: Int
, repoForks :: Int
, repoFork :: Bool
, repoSize :: Int
, repoOwner :: User
, repoPrivate :: Bool
, repoOpenIssues :: Int
, repoHasIssues :: Bool
, repoHasDownloads :: Bool
, repoHasWiki :: Bool
, repoLanguage :: Text
, repoCreatedAt :: Int
, repoPushedAt :: Int
, repoMasterBranch :: Text
} deriving (Show, Eq, Typeable)
instance FromJSON Repository where
parseJSON (Object o) = Repository
<$> o .: "id"
<*> o .: "name"
<*> o .: "url"
<*> o .: "description"
<*> o .:? "homepage"
<*> o .: "watchers"
<*> o .: "stargazers"
<*> o .: "forks"
<*> o .: "fork"
<*> o .: "size"
<*> o .: "owner"
<*> o .: "private"
<*> o .: "open_issues"
<*> o .: "has_issues"
<*> o .: "has_downloads"
<*> o .: "has_wiki"
<*> o .: "language"
<*> o .: "created_at"
<*> o .: "pushed_at"
<*> o .: "master_branch"
parseJSON _ = fail "Repository must be an object"
data User = User
{ userName :: Text
, userEmail :: Maybe EmailAddress
, userUsername :: Maybe Text
} deriving (Show, Eq, Typeable)
instance FromJSON User where
parseJSON (Object o) = User
<$> o .: "name"
<*> o .:? "email"
<*> o .:? "username"
parseJSON _ = fail "User must be an object"
instance FromJSON EmailAddress where
parseJSON (String t) = case emailAddress $ B.pack . T.unpack $ t of
Just a -> pure a
Nothing -> fail "failed to parse EmailAddress"
parseJSON _ = fail "EmailAddress must be a text"