{-# LANGUAGE TemplateHaskell #-}

-- | Command prefix parsing effect
module CalamityCommands.ParsePrefix (
  ParsePrefix (..),
  parsePrefix,
  useConstantPrefix,
) where

import qualified Data.Text as T

import qualified Polysemy as P

-- | An effect for parsing the prefix of a command.
data ParsePrefix msg m a where
  -- | Parse a prefix in a message, returning a tuple of @(prefix, remaining message)@
  ParsePrefix :: msg -> ParsePrefix msg m (Maybe (T.Text, T.Text))

P.makeSem ''ParsePrefix

-- | A default interpretation for 'ParsePrefix' that uses a single constant prefix.
useConstantPrefix :: T.Text -> P.Sem (ParsePrefix T.Text ': r) a -> P.Sem r a
useConstantPrefix :: Text -> Sem (ParsePrefix Text : r) a -> Sem r a
useConstantPrefix Text
pre =
  (forall (rInitial :: EffectRow) x.
 ParsePrefix Text (Sem rInitial) x -> Sem r x)
-> Sem (ParsePrefix Text : r) a -> Sem r a
forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
FirstOrder e "interpret" =>
(forall (rInitial :: EffectRow) x. e (Sem rInitial) x -> Sem r x)
-> Sem (e : r) a -> Sem r a
P.interpret
    ( \case
        ParsePrefix msg -> Maybe (Text, Text) -> Sem r (Maybe (Text, Text))
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Text
pre,) (Text -> (Text, Text)) -> Maybe Text -> Maybe (Text, Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Text -> Maybe Text
T.stripPrefix Text
pre Text
msg)
    )