{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards   #-}
{-# LANGUAGE StrictData        #-}
module GitHub.Types.Base.Commit where

import           Data.Aeson                   (FromJSON (..), ToJSON (..),
                                               object)
import           Data.Aeson.Types             (Value (..), (.:), (.:?), (.=))
import           Data.Text                    (Text)
import           Test.QuickCheck.Arbitrary    (Arbitrary (..))

import           GitHub.Types.Base.Repository
import           GitHub.Types.Base.User

------------------------------------------------------------------------------
-- Commit

data Commit = Commit
    { Commit -> Text
commitSha   :: Text
    , Commit -> Maybe User
commitUser  :: Maybe User
    , Commit -> Maybe Repository
commitRepo  :: Maybe Repository
    , Commit -> Text
commitLabel :: Text
    , Commit -> Text
commitRef   :: Text
    } deriving (Commit -> Commit -> Bool
(Commit -> Commit -> Bool)
-> (Commit -> Commit -> Bool) -> Eq Commit
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Commit -> Commit -> Bool
$c/= :: Commit -> Commit -> Bool
== :: Commit -> Commit -> Bool
$c== :: Commit -> Commit -> Bool
Eq, Int -> Commit -> ShowS
[Commit] -> ShowS
Commit -> String
(Int -> Commit -> ShowS)
-> (Commit -> String) -> ([Commit] -> ShowS) -> Show Commit
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Commit] -> ShowS
$cshowList :: [Commit] -> ShowS
show :: Commit -> String
$cshow :: Commit -> String
showsPrec :: Int -> Commit -> ShowS
$cshowsPrec :: Int -> Commit -> ShowS
Show, ReadPrec [Commit]
ReadPrec Commit
Int -> ReadS Commit
ReadS [Commit]
(Int -> ReadS Commit)
-> ReadS [Commit]
-> ReadPrec Commit
-> ReadPrec [Commit]
-> Read Commit
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Commit]
$creadListPrec :: ReadPrec [Commit]
readPrec :: ReadPrec Commit
$creadPrec :: ReadPrec Commit
readList :: ReadS [Commit]
$creadList :: ReadS [Commit]
readsPrec :: Int -> ReadS Commit
$creadsPrec :: Int -> ReadS Commit
Read)


instance FromJSON Commit where
    parseJSON :: Value -> Parser Commit
parseJSON (Object Object
x) = Text -> Maybe User -> Maybe Repository -> Text -> Text -> Commit
Commit
        (Text -> Maybe User -> Maybe Repository -> Text -> Text -> Commit)
-> Parser Text
-> Parser
     (Maybe User -> Maybe Repository -> Text -> Text -> Commit)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
x Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"sha"
        Parser (Maybe User -> Maybe Repository -> Text -> Text -> Commit)
-> Parser (Maybe User)
-> Parser (Maybe Repository -> Text -> Text -> Commit)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
x Object -> Key -> Parser (Maybe User)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"user"
        Parser (Maybe Repository -> Text -> Text -> Commit)
-> Parser (Maybe Repository) -> Parser (Text -> Text -> Commit)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
x Object -> Key -> Parser (Maybe Repository)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"repo"
        Parser (Text -> Text -> Commit)
-> Parser Text -> Parser (Text -> Commit)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
x Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"label"
        Parser (Text -> Commit) -> Parser Text -> Parser Commit
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
x Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"ref"

    parseJSON Value
_ = String -> Parser Commit
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Commit"


instance ToJSON Commit where
    toJSON :: Commit -> Value
toJSON Commit{Maybe User
Maybe Repository
Text
commitRef :: Text
commitLabel :: Text
commitRepo :: Maybe Repository
commitUser :: Maybe User
commitSha :: Text
commitRef :: Commit -> Text
commitLabel :: Commit -> Text
commitRepo :: Commit -> Maybe Repository
commitUser :: Commit -> Maybe User
commitSha :: Commit -> Text
..} = [Pair] -> Value
object
        [ Key
"sha"   Key -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Text
commitSha
        , Key
"user"  Key -> Maybe User -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe User
commitUser
        , Key
"repo"  Key -> Maybe Repository -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe Repository
commitRepo
        , Key
"label" Key -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Text
commitLabel
        , Key
"ref"   Key -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Text
commitRef
        ]


instance Arbitrary Commit where
    arbitrary :: Gen Commit
arbitrary = Text -> Maybe User -> Maybe Repository -> Text -> Text -> Commit
Commit
        (Text -> Maybe User -> Maybe Repository -> Text -> Text -> Commit)
-> Gen Text
-> Gen (Maybe User -> Maybe Repository -> Text -> Text -> Commit)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Text
forall a. Arbitrary a => Gen a
arbitrary
        Gen (Maybe User -> Maybe Repository -> Text -> Text -> Commit)
-> Gen (Maybe User)
-> Gen (Maybe Repository -> Text -> Text -> Commit)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen (Maybe User)
forall a. Arbitrary a => Gen a
arbitrary
        Gen (Maybe Repository -> Text -> Text -> Commit)
-> Gen (Maybe Repository) -> Gen (Text -> Text -> Commit)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen (Maybe Repository)
forall a. Arbitrary a => Gen a
arbitrary
        Gen (Text -> Text -> Commit) -> Gen Text -> Gen (Text -> Commit)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Text
forall a. Arbitrary a => Gen a
arbitrary
        Gen (Text -> Commit) -> Gen Text -> Gen Commit
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Text
forall a. Arbitrary a => Gen a
arbitrary