{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE CPP #-}
module Telegram.Bot.Simple.UpdateParser where
import Control.Applicative
import Control.Monad.Reader
#if defined(MIN_VERSION_GLASGOW_HASKELL)
#if MIN_VERSION_GLASGOW_HASKELL(8,6,2,0)
#else
import Data.Monoid ((<>))
#endif
#endif
import qualified Data.Char as Char
import Data.Text (Text)
import qualified Data.Text as Text
import Text.Read (readMaybe)
import Telegram.Bot.API
newtype UpdateParser a = UpdateParser
{ forall a. UpdateParser a -> Update -> Maybe a
runUpdateParser :: Update -> Maybe a
} deriving (forall a b. a -> UpdateParser b -> UpdateParser a
forall a b. (a -> b) -> UpdateParser a -> UpdateParser b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> UpdateParser b -> UpdateParser a
$c<$ :: forall a b. a -> UpdateParser b -> UpdateParser a
fmap :: forall a b. (a -> b) -> UpdateParser a -> UpdateParser b
$cfmap :: forall a b. (a -> b) -> UpdateParser a -> UpdateParser b
Functor)
instance Applicative UpdateParser where
pure :: forall a. a -> UpdateParser a
pure a
x = forall a. (Update -> Maybe a) -> UpdateParser a
UpdateParser (forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
x))
UpdateParser Update -> Maybe (a -> b)
f <*> :: forall a b.
UpdateParser (a -> b) -> UpdateParser a -> UpdateParser b
<*> UpdateParser Update -> Maybe a
x = forall a. (Update -> Maybe a) -> UpdateParser a
UpdateParser (\Update
u -> Update -> Maybe (a -> b)
f Update
u forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Update -> Maybe a
x Update
u)
instance Alternative UpdateParser where
empty :: forall a. UpdateParser a
empty = forall a. (Update -> Maybe a) -> UpdateParser a
UpdateParser (forall a b. a -> b -> a
const forall a. Maybe a
Nothing)
UpdateParser Update -> Maybe a
f <|> :: forall a. UpdateParser a -> UpdateParser a -> UpdateParser a
<|> UpdateParser Update -> Maybe a
g = forall a. (Update -> Maybe a) -> UpdateParser a
UpdateParser (\Update
u -> Update -> Maybe a
f Update
u forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Update -> Maybe a
g Update
u)
instance Monad UpdateParser where
return :: forall a. a -> UpdateParser a
return = forall (f :: * -> *) a. Applicative f => a -> f a
pure
UpdateParser Update -> Maybe a
x >>= :: forall a b.
UpdateParser a -> (a -> UpdateParser b) -> UpdateParser b
>>= a -> UpdateParser b
f = forall a. (Update -> Maybe a) -> UpdateParser a
UpdateParser (\Update
u -> Update -> Maybe a
x Update
u forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. UpdateParser a -> Update -> Maybe a
runUpdateParser Update
u forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> UpdateParser b
f)
#if !MIN_VERSION_base(4,13,0)
fail _ = empty
#endif
#if MIN_VERSION_base(4,13,0)
instance MonadFail UpdateParser where
fail :: forall a. String -> UpdateParser a
fail String
_ = forall (f :: * -> *) a. Alternative f => f a
empty
#endif
mkParser :: (Update -> Maybe a) -> UpdateParser a
mkParser :: forall a. (Update -> Maybe a) -> UpdateParser a
mkParser = forall a. (Update -> Maybe a) -> UpdateParser a
UpdateParser
parseUpdate :: UpdateParser a -> Update -> Maybe a
parseUpdate :: forall a. UpdateParser a -> Update -> Maybe a
parseUpdate = forall a. UpdateParser a -> Update -> Maybe a
runUpdateParser
text :: UpdateParser Text
text :: UpdateParser Text
text = forall a. (Update -> Maybe a) -> UpdateParser a
UpdateParser (Update -> Maybe Message
extractUpdateMessage forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Message -> Maybe Text
messageText)
plainText :: UpdateParser Text
plainText :: UpdateParser Text
plainText = do
Text
t <- UpdateParser Text
text
if Text
"/" Text -> Text -> Bool
`Text.isPrefixOf` Text
t
then forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"command"
else forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
t
command :: Text -> UpdateParser Text
command :: Text -> UpdateParser Text
command Text
name = do
Text
t <- UpdateParser Text
text
let (Text
cmd, Text
rest) = (Char -> Bool) -> Text -> (Text, Text)
Text.break Char -> Bool
Char.isSpace Text
t
if Text
cmd forall a. Eq a => a -> a -> Bool
== Text
"/" forall a. Semigroup a => a -> a -> a
<> Text
name
then forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Text -> Text
Text.stripStart Text
rest
else forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"not that command"
commandWithBotName :: Text -> Text -> UpdateParser Text
commandWithBotName :: Text -> Text -> UpdateParser Text
commandWithBotName Text
botname Text
commandname = do
Text
t <- UpdateParser Text
text
let (Text
cmd, Text
rest) = (Char -> Bool) -> Text -> (Text, Text)
Text.break Char -> Bool
Char.isSpace Text
t
if Text
cmd forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"/" forall a. Semigroup a => a -> a -> a
<> Text
commandname forall a. Semigroup a => a -> a -> a
<> Text
"@" forall a. Semigroup a => a -> a -> a
<> Text
botname, Text
"/" forall a. Semigroup a => a -> a -> a
<> Text
commandname]
then forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Text -> Text
Text.stripStart Text
rest
else forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"not that command"
callbackQueryDataRead :: Read a => UpdateParser a
callbackQueryDataRead :: forall a. Read a => UpdateParser a
callbackQueryDataRead = forall a. (Update -> Maybe a) -> UpdateParser a
mkParser forall a b. (a -> b) -> a -> b
$ \Update
update -> do
CallbackQuery
query <- Update -> Maybe CallbackQuery
updateCallbackQuery Update
update
Text
data_ <- CallbackQuery -> Maybe Text
callbackQueryData CallbackQuery
query
forall a. Read a => String -> Maybe a
readMaybe (Text -> String
Text.unpack Text
data_)
updateMessageText :: Update -> Maybe Text
updateMessageText :: Update -> Maybe Text
updateMessageText = Update -> Maybe Message
extractUpdateMessage forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Message -> Maybe Text
messageText
updateMessageSticker :: Update -> Maybe Sticker
updateMessageSticker :: Update -> Maybe Sticker
updateMessageSticker = Update -> Maybe Message
extractUpdateMessage forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Message -> Maybe Sticker
messageSticker