todoist-sdk-0.1.2.1: src/Web/Todoist/Util/Builder.hs
{-# LANGUAGE RankNTypes #-}
{- | Builder pattern for constructing domain types with optional fields.
This module provides a type-safe builder pattern for creating domain request types
(like ProjectCreate, TaskCreate, etc.) with ergonomic field setting.
Example usage:
@
let project = runBuilder (createProjectBuilder \"My Project\")
(withDescription \"A description\" <> withViewStyle Board)
@
-}
module Web.Todoist.Util.Builder
( -- * Builder Core Types
Builder
, Initial
, runBuilder
, seed
-- * Setter Functions
, withDescription
, withParentId
, withProjectId
, withTaskId
, withViewStyle
, withWorkspaceId
, withName
, withIsFavorite
, withContent
, withColor
, withSectionId
, withOrder
, withLabels
, withPriority
, withAssigneeId
, withDueString
, withDueDate
, withDueDatetime
, withDueLang
, withDuration
, withDurationUnit
, withDeadlineDate
, withAttachment
, withUidsToNotify
, withCursor
, withLimit
, withQuery
, withLang
, withSince
, withUntil
, withTaskIds
, withPublicKey
, withOmitPersonal
, withFilterQuery
, withFilterLang
-- * Type Classes (for implementing Has* instances)
, HasDescription (..)
, HasParentId (..)
, HasProjectId (..)
, HasViewStyle (..)
, HasWorkspaceId (..)
, HasName (..)
, HasIsFavorite (..)
, HasContent (..)
, HasSectionId (..)
, HasOrder (..)
, HasLabels (..)
, HasPriority (..)
, HasAssigneeId (..)
, HasDueString (..)
, HasDueDate (..)
, HasDueDatetime (..)
, HasDueLang (..)
, HasDuration (..)
, HasDurationUnit (..)
, HasDeadlineDate (..)
, HasTaskId (..)
, HasUidsToNotify (..)
, HasAttachment (..)
, HasColor (..)
, HasCursor (..)
, HasLimit (..)
, HasQuery (..)
, HasLang (..)
, HasSince (..)
, HasUntil (..)
, HasTaskIds (..)
, HasPublicKey (..)
, HasOmitPersonal (..)
, HasFilterQuery (..)
, HasFilterLang (..)
) where
import Web.Todoist.Domain.Types (Attachment, ViewStyle)
import Data.Bool (Bool)
import Data.Int (Int)
import Data.Monoid (Dual (..), Endo (..), Monoid (..))
import Data.Semigroup (Semigroup (..))
import Data.Text (Text)
-- ============================================================================
-- Type Classes
-- ============================================================================
class HasDescription p where
hasDescription :: Text -> p -> p
class HasParentId p where
hasParentId :: Text -> p -> p
class HasProjectId p where
hasProjectId :: Text -> p -> p
class HasViewStyle p where
hasViewStyle :: ViewStyle -> p -> p
class HasWorkspaceId p where
hasWorkspaceId :: Int -> p -> p
-- | Type class for types that have a name field
class HasName p where
hasName :: Text -> p -> p
-- | Type class for types that have an is_favorite field
class HasIsFavorite p where
hasIsFavorite :: Bool -> p -> p
class HasContent p where
hasContent :: Text -> p -> p
class HasSectionId p where
hasSectionId :: Text -> p -> p
class HasOrder p where
hasOrder :: Int -> p -> p
class HasLabels p where
hasLabels :: [Text] -> p -> p
class HasPriority p where
hasPriority :: Int -> p -> p
class HasAssigneeId p where
hasAssigneeId :: Int -> p -> p
class HasDueString p where
hasDueString :: Text -> p -> p
class HasDueDate p where
hasDueDate :: Text -> p -> p
class HasDueDatetime p where
hasDueDatetime :: Text -> p -> p
class HasDueLang p where
hasDueLang :: Text -> p -> p
class HasDuration p where
hasDuration :: Int -> p -> p
class HasDurationUnit p where
hasDurationUnit :: Text -> p -> p
class HasDeadlineDate p where
hasDeadlineDate :: Text -> p -> p
-- Comment-specific setters
class HasTaskId p where
hasTaskId :: Text -> p -> p
class HasUidsToNotify p where
hasUidsToNotify :: [Int] -> p -> p
class HasAttachment p where
hasAttachment :: Attachment -> p -> p
class HasColor p where
hasColor :: Text -> p -> p
-- QueryParam-specific type classes
class HasCursor p where
hasCursor :: Text -> p -> p
class HasLimit p where
hasLimit :: Int -> p -> p
class HasQuery p where
hasQuery :: Text -> p -> p
class HasLang p where
hasLang :: Text -> p -> p
class HasSince p where
hasSince :: Text -> p -> p
class HasUntil p where
hasUntil :: Text -> p -> p
class HasTaskIds p where
hasTaskIds :: [Text] -> p -> p
class HasPublicKey p where
hasPublicKey :: Text -> p -> p
class HasOmitPersonal p where
hasOmitPersonal :: Bool -> p -> p
class HasFilterQuery p where
hasFilterQuery :: Text -> p -> p
class HasFilterLang p where
hasFilterLang :: Text -> p -> p
-- ============================================================================
-- Builder Types and Functions
-- ============================================================================
-- Newtype for seed values (constructor NOT exported)
newtype Initial s = Initial s
newtype Builder s = Builder
{ bMods :: Dual (Endo s) -- Dual for left-to-right application order
}
instance Semigroup (Builder s) where
(<>) :: Builder s -> Builder s -> Builder s
Builder md1 <> Builder md2 = Builder (md1 <> md2)
instance Monoid (Builder s) where
mempty :: Builder s
mempty = Builder mempty
runBuilder :: Initial s -> Builder s -> s
runBuilder (Initial s) (Builder (Dual (Endo f))) = f s
seed :: s -> Initial s
seed = Initial
modB :: (s -> s) -> Builder s
modB f = Builder {bMods = Dual {getDual = Endo {appEndo = f}}}
-- ============================================================================
-- Setter Functions
-- ============================================================================
-- | Set the description field for projects or tasks
withDescription :: (HasDescription s) => Text -> Builder s
withDescription desc = modB (hasDescription desc)
-- | Set the parent project or task ID for hierarchical organization
withParentId :: (HasParentId s) => Text -> Builder s
withParentId pid = modB (hasParentId pid)
-- | Set the project ID to assign a task to a specific project
withProjectId :: (HasProjectId s) => Text -> Builder s
withProjectId pid = modB (hasProjectId pid)
-- | Set the view style for a project (List, Board, or Calendar)
withViewStyle :: (HasViewStyle s) => ViewStyle -> Builder s
withViewStyle style = modB (hasViewStyle style)
-- | Set the workspace ID for team/workspace assignment
withWorkspaceId :: (HasWorkspaceId s) => Int -> Builder s
withWorkspaceId wid = modB (hasWorkspaceId wid)
-- | Set the name field for projects, sections, or labels
withName :: (HasName s) => Text -> Builder s
withName name = modB (hasName name)
-- | Set whether an item is marked as favorite
withIsFavorite :: (HasIsFavorite s) => Bool -> Builder s
withIsFavorite fav = modB (hasIsFavorite fav)
-- | Set the content (title/description) field for tasks
withContent :: (HasContent s) => Text -> Builder s
withContent content = modB (hasContent content)
-- | Set the color field for labels
withColor :: (HasColor s) => Text -> Builder s
withColor color = modB (hasColor color)
-- | Set the section ID to organize a task within a project section
withSectionId :: (HasSectionId s) => Text -> Builder s
withSectionId sid = modB (hasSectionId sid)
-- | Set the sort order (lower numbers appear first)
withOrder :: (HasOrder s) => Int -> Builder s
withOrder order = modB (hasOrder order)
-- | Set the list of label names to tag a task
withLabels :: (HasLabels s) => [Text] -> Builder s
withLabels labels = modB (hasLabels labels)
-- | Set the priority level (1=urgent, 2=high, 3=normal, 4=low)
withPriority :: (HasPriority s) => Int -> Builder s
withPriority priority = modB (hasPriority priority)
-- | Set the assignee user ID for task assignment
withAssigneeId :: (HasAssigneeId s) => Int -> Builder s
withAssigneeId aid = modB (hasAssigneeId aid)
-- | Set a natural language due date string (e.g., \"tomorrow\", \"next Monday\")
withDueString :: (HasDueString s) => Text -> Builder s
withDueString dueStr = modB (hasDueString dueStr)
-- | Set the due date in YYYY-MM-DD format
withDueDate :: (HasDueDate s) => Text -> Builder s
withDueDate dueDate = modB (hasDueDate dueDate)
-- | Set the due datetime in RFC3339 format with timezone
withDueDatetime :: (HasDueDatetime s) => Text -> Builder s
withDueDatetime dueDatetime = modB (hasDueDatetime dueDatetime)
-- | Set the language code for parsing natural language due strings
withDueLang :: (HasDueLang s) => Text -> Builder s
withDueLang dueLang = modB (hasDueLang dueLang)
-- | Set the task duration amount (used with duration_unit)
withDuration :: (HasDuration s) => Int -> Builder s
withDuration duration = modB (hasDuration duration)
-- | Set the task duration unit (\"minute\" or \"day\")
withDurationUnit :: (HasDurationUnit s) => Text -> Builder s
withDurationUnit durationUnit = modB (hasDurationUnit durationUnit)
-- | Set the deadline date for a task
withDeadlineDate :: (HasDeadlineDate s) => Text -> Builder s
withDeadlineDate deadlineDate = modB (hasDeadlineDate deadlineDate)
-- | Set an attachment for a comment
withAttachment :: (HasAttachment s) => Attachment -> Builder s
withAttachment attachment = modB (hasAttachment attachment)
-- | Set the task ID for comments to associate a comment with a task
withTaskId :: (HasTaskId s) => Text -> Builder s
withTaskId tid = modB (hasTaskId tid)
-- | Set the list of user IDs to notify about a comment
withUidsToNotify :: (HasUidsToNotify s) => [Int] -> Builder s
withUidsToNotify uids = modB (hasUidsToNotify uids)
-- | Set the pagination cursor for fetching the next page of results
withCursor :: (HasCursor s) => Text -> Builder s
withCursor cursor = modB (hasCursor cursor)
-- | Set the maximum number of items to return per page
withLimit :: (HasLimit s) => Int -> Builder s
withLimit limit = modB (hasLimit limit)
-- | Set the search query text for filtering items
withQuery :: (HasQuery s) => Text -> Builder s
withQuery query = modB (hasQuery query)
-- | Set the language code for natural language processing
withLang :: (HasLang s) => Text -> Builder s
withLang lang = modB (hasLang lang)
-- | Set the start date for date range filtering
withSince :: (HasSince s) => Text -> Builder s
withSince since = modB (hasSince since)
-- | Set the end date for date range filtering
withUntil :: (HasUntil s) => Text -> Builder s
withUntil until = modB (hasUntil until)
-- | Set the list of task IDs for filtering by specific tasks
withTaskIds :: (HasTaskIds s) => [Text] -> Builder s
withTaskIds taskIds = modB (hasTaskIds taskIds)
-- | Set the public key for accessing shared comments
withPublicKey :: (HasPublicKey s) => Text -> Builder s
withPublicKey publicKey = modB (hasPublicKey publicKey)
-- | Set whether to omit personal labels from results
withOmitPersonal :: (HasOmitPersonal s) => Bool -> Builder s
withOmitPersonal omitPersonal = modB (hasOmitPersonal omitPersonal)
-- | Set the filter query for completed tasks
withFilterQuery :: (HasFilterQuery s) => Text -> Builder s
withFilterQuery filterQuery = modB (hasFilterQuery filterQuery)
-- | Set the filter language for completed tasks
withFilterLang :: (HasFilterLang s) => Text -> Builder s
withFilterLang filterLang = modB (hasFilterLang filterLang)