module GitHub.Data.Request (
Request (..),
SimpleRequest (..),
query, pagedQuery, command,
RW(..),
StatusMap,
statusOnlyOk,
CommandMethod(..),
toMethod,
FetchCount(..),
Paths,
IsPathPart(..),
QueryString,
Count,
) where
import GitHub.Data.Definitions (Count, QueryString)
import GitHub.Data.Id (Id, untagId)
import GitHub.Data.Name (Name, untagName)
import GitHub.Internal.Prelude
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Text as T
import qualified Network.HTTP.Types as Types
import qualified Network.HTTP.Types.Method as Method
type Paths = [Text]
class IsPathPart a where
toPathPart :: a -> Text
instance IsPathPart (Name a) where
toPathPart = untagName
instance IsPathPart (Id a) where
toPathPart = T.pack . show . untagId
data CommandMethod a where
Post :: CommandMethod a
Patch :: CommandMethod a
Put :: CommandMethod a
Put' :: CommandMethod ()
Delete :: CommandMethod ()
deriving (Typeable)
deriving instance Eq (CommandMethod a)
instance Show (CommandMethod a) where
showsPrec _ Post = showString "Post"
showsPrec _ Patch = showString "Patch"
showsPrec _ Put = showString "Put"
showsPrec _ Put' = showString "Put'"
showsPrec _ Delete = showString "Delete"
instance Hashable (CommandMethod a) where
hashWithSalt salt Post = hashWithSalt salt (0 :: Int)
hashWithSalt salt Patch = hashWithSalt salt (1 :: Int)
hashWithSalt salt Put = hashWithSalt salt (2 :: Int)
hashWithSalt salt Put' = hashWithSalt salt (3 :: Int)
hashWithSalt salt Delete = hashWithSalt salt (4 :: Int)
toMethod :: CommandMethod a -> Method.Method
toMethod Post = Method.methodPost
toMethod Patch = Method.methodPatch
toMethod Put = Method.methodPut
toMethod Put' = Method.methodPut
toMethod Delete = Method.methodDelete
data FetchCount = FetchAtLeast !Word | FetchAll
deriving (Eq, Ord, Read, Show, Generic, Typeable)
instance Num FetchCount where
fromInteger = FetchAtLeast . fromInteger
FetchAtLeast a + FetchAtLeast b = FetchAtLeast (a * b)
_ + _ = FetchAll
FetchAtLeast a * FetchAtLeast b = FetchAtLeast (a * b)
_ * _ = FetchAll
abs = error "abs @FetchCount: not implemented"
signum = error "signum @FetchCount: not implemented"
negate = error "negate @FetchCount: not implemented"
instance Hashable FetchCount
instance Binary FetchCount
instance NFData FetchCount where rnf = genericRnf
data RW
= RO
| RA
| RW
deriving (Eq, Ord, Read, Show, Enum, Bounded, Typeable, Data, Generic)
data Request (k :: RW) a where
SimpleQuery :: FromJSON a => SimpleRequest k a -> Request k a
StatusQuery :: StatusMap a -> SimpleRequest k () -> Request k a
HeaderQuery :: FromJSON a => Types.RequestHeaders -> SimpleRequest k a -> Request k a
deriving (Typeable)
data SimpleRequest (k :: RW) a where
Query :: Paths -> QueryString -> SimpleRequest k a
PagedQuery :: Paths -> QueryString -> FetchCount -> SimpleRequest k (Vector a)
Command :: CommandMethod a -> Paths -> LBS.ByteString -> SimpleRequest 'RW a
deriving (Typeable)
type StatusMap a = [(Int, a)]
statusOnlyOk :: StatusMap Bool
statusOnlyOk =
[ (202, True)
, (404, False)
]
query :: FromJSON a => Paths -> QueryString -> Request k a
query ps qs = SimpleQuery (Query ps qs)
pagedQuery :: FromJSON a => Paths -> QueryString -> FetchCount -> Request k (Vector a)
pagedQuery ps qs fc = SimpleQuery (PagedQuery ps qs fc)
command :: FromJSON a => CommandMethod a -> Paths -> LBS.ByteString -> Request 'RW a
command m ps body = SimpleQuery (Command m ps body)
deriving instance Eq a => Eq (Request k a)
deriving instance Eq a => Eq (SimpleRequest k a)
instance Show (SimpleRequest k a) where
showsPrec d r = showParen (d > appPrec) $ case r of
Query ps qs -> showString "Query "
. showsPrec (appPrec + 1) ps
. showString " "
. showsPrec (appPrec + 1) qs
PagedQuery ps qs l -> showString "PagedQuery "
. showsPrec (appPrec + 1) ps
. showString " "
. showsPrec (appPrec + 1) qs
. showString " "
. showsPrec (appPrec + 1) l
Command m ps body -> showString "Command "
. showsPrec (appPrec + 1) m
. showString " "
. showsPrec (appPrec + 1) ps
. showString " "
. showsPrec (appPrec + 1) body
where
appPrec = 10 :: Int
instance Show (Request k a) where
showsPrec d r = showParen (d > appPrec) $ case r of
SimpleQuery req -> showString "SimpleQuery "
. showsPrec (appPrec + 1) req
StatusQuery m req -> showString "Status "
. showsPrec (appPrec + 1) (map fst m)
. showString " "
. showsPrec (appPrec + 1) req
HeaderQuery m req -> showString "Header "
. showsPrec (appPrec + 1) m
. showString " "
. showsPrec (appPrec + 1) req
where
appPrec = 10 :: Int
instance Hashable (SimpleRequest k a) where
hashWithSalt salt (Query ps qs) =
salt `hashWithSalt` (0 :: Int)
`hashWithSalt` ps
`hashWithSalt` qs
hashWithSalt salt (PagedQuery ps qs l) =
salt `hashWithSalt` (1 :: Int)
`hashWithSalt` ps
`hashWithSalt` qs
`hashWithSalt` l
hashWithSalt salt (Command m ps body) =
salt `hashWithSalt` (2 :: Int)
`hashWithSalt` m
`hashWithSalt` ps
`hashWithSalt` body
instance Hashable (Request k a) where
hashWithSalt salt (SimpleQuery req) =
salt `hashWithSalt` (0 :: Int)
`hashWithSalt` req
hashWithSalt salt (StatusQuery sm req) =
salt `hashWithSalt` (1 :: Int)
`hashWithSalt` map fst sm
`hashWithSalt` req
hashWithSalt salt (HeaderQuery h req) =
salt `hashWithSalt` (2 :: Int)
`hashWithSalt` h
`hashWithSalt` req