Skip to content

Instantly share code, notes, and snippets.

@Jacoby6000
Created May 18, 2025 18:10
Show Gist options
  • Save Jacoby6000/1b37e6f369317adda76bbc076b564e1f to your computer and use it in GitHub Desktop.
Save Jacoby6000/1b37e6f369317adda76bbc076b564e1f to your computer and use it in GitHub Desktop.
module Bot.Interaction.Options
( getOptionByName
, processStringOption
, processBoolOption
, processIntOption
, processNumberOption
, processUserOption
, processRoleOption
, getStringOption
, getBoolOption
, getIntOption
, getNumberOption
, getUserOption
, getRoleOption
, readOption
) where
import Control.Monad (MonadPlus(mzero))
import qualified Data.Foldable as F
import Data.Text
import Discord.Interactions (Number, OptionDataValue(..))
import Discord.Types (RoleId, UserId)
-- | Processes the option with the given name from the list of options, given an processor function
-- When the option is not found, it returns mzero
-- When the option is found, it applies the processor function to the option
--
-- For example, if you have a user option with name "foo", you could use
-- readOption "foo" processUserOption opts
readOption ::
MonadPlus m => Text -> (OptionDataValue -> m a) -> [OptionDataValue] -> m a
readOption name processor opts =
maybe mzero processor (F.find (\opt -> optionDataValueName opt == name) opts)
-- | fFnds an option from the list of options, given a name
getOptionByName :: MonadPlus m => Text -> [OptionDataValue] -> m OptionDataValue
getOptionByName name opts =
maybe mzero pure (F.find (\opt -> optionDataValueName opt == name) opts)
-- | Converts an OptionDataValue in to the text assosciated with the option
-- If the option was not an OptionDataValueString
processStringOption :: MonadPlus m => OptionDataValue -> m Text
processStringOption (OptionDataValueString _ (Right s)) = pure s
processStringOption _ = mzero
-- | Given an Option name and a list of options, attempts to find the option with the provided name and return the
-- text value that the user provided.
--
-- Returns mzero if the option is not found or if the option is not a string.
getStringOption :: MonadPlus m => Text -> [OptionDataValue] -> m Text
getStringOption name opts = getOptionByName name opts >>= processStringOption
-- | Converts an OptionDataValue in to the bool assosciated with the option
--
-- Returns mzero If the option was not an OptionDataValueBoolean
processBoolOption :: MonadPlus m => OptionDataValue -> m Bool
processBoolOption (OptionDataValueBoolean _ b) = pure b
processBoolOption _ = mzero
-- | Given an Option name and a list of options, attempts to find the option with the provided name and return the
-- boolean value that the user provided.
--
-- Returns mzero if the option is not found or if the option is not a boolean.
getBoolOption :: MonadPlus m => Text -> [OptionDataValue] -> m Bool
getBoolOption name opts = getOptionByName name opts >>= processBoolOption
-- | Converts an OptionDataValue in to the int assosciated with the option
--
-- Returns mzero If the option was not an OptionDataValueInteger
processIntOption :: MonadPlus m => OptionDataValue -> m Integer
processIntOption (OptionDataValueInteger _ (Right i)) = pure i
processIntOption _ = mzero
-- | Given an Option name and a list of options, attempts to find the option with the provided name and return the
-- integer value that the user provided.
--
-- Returns mzero if the option is not found or if the option is not an integer.
getIntOption :: MonadPlus m => Text -> [OptionDataValue] -> m Integer
getIntOption name opts = getOptionByName name opts >>= processIntOption
-- | Converts an OptionDataValue in to the number assosciated with the option
--
-- Returns mzero If the option was not an OptionDataValueNumber
processNumberOption :: MonadPlus m => OptionDataValue -> m Number
processNumberOption (OptionDataValueNumber _ (Right n)) = pure n
processNumberOption _ = mzero
-- | Given an Option name and a list of options, attempts to find the option with the provided name and return the
-- Number value that the user provided.
--
-- Returns mzero if the option is not found or if the option is not a number.
getNumberOption :: MonadPlus m => Text -> [OptionDataValue] -> m Number
getNumberOption name opts = getOptionByName name opts >>= processNumberOption
-- | Converts an OptionDataValue in to the user assosciated with the option
--
-- Returns mzero If the option was not an OptionDataValueUser
processUserOption :: MonadPlus m => OptionDataValue -> m UserId
processUserOption (OptionDataValueUser _ u) = pure u
processUserOption _ = mzero
-- | Given an Option name and a list of options, attempts to find the option with the provided name and return the
-- UserId value that the user provided.
--
-- Returns mzero if the option is not found or if the option is not a user.
getUserOption :: MonadPlus m => Text -> [OptionDataValue] -> m UserId
getUserOption name opts = getOptionByName name opts >>= processUserOption
-- | Converts an OptionDataValue in to the role assosciated with the option
--
-- Returns mzero If the option was not an OptionDataValueRole
processRoleOption :: MonadPlus m => OptionDataValue -> m RoleId
processRoleOption (OptionDataValueRole _ r) = pure r
processRoleOption _ = mzero
-- | Given an Option name and a list of options, attempts to find the option with the provided name and return the
-- id of the role that the user provided.
--
-- Returns mzero if the option is not found or if the option is not a role.
getRoleOption :: MonadPlus m => Text -> [OptionDataValue] -> m RoleId
getRoleOption name opts = getOptionByName name opts >>= processRoleOption
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment