restman-0.7.4.0: src/Types.hs
{-|
Module: Types
Core data types for the RESTman TUI.
'AppS' is the top-level application state. It is threaded through the Brick event loop and
holds all mutable information: the focused widget, editor contents, the HTTP connection
manager, and the last rendered response image.
'AppR' is the resource name type used to identify named Brick widgets (editors, viewports,
etc.).
See also 'Lib' for the functions that manipulate these types.
-}
module Types
( -- * Global Types for TUI manipulation
AppS(..)
, OverlayS(..)
, AppR(..)
, CustomHeaderR(..)
, CustomHeaderColumn(..)
-- * Range Ord-like types and helpers
, RangeInAlign(..)
, VertAlign
, WideAlign
, left
, top
) where
-- brick
import Brick.Types (Extent)
import Brick.Widgets.Edit (Editor)
import Brick.Widgets.List (List)
-- bytestring
import qualified Data.ByteString.Lazy as Lazy (ByteString)
-- http-client
import qualified Network.HTTP.Client as HC
-- text
import Data.Text (Text)
-- vty
import Graphics.Vty.Image (Image)
-- internal imports
import HTTP.Client (Header, Method)
{-|
Application State
Single URL editor widget.
Widget names are all 'Text' values.
-}
data AppS = AppS
{ focus :: AppR -- ^ Focus tracking within the main interface.
, methodEditor :: !(Editor Method AppR) -- ^ text entry for the HTTP method to use for request
, overlayState :: !(Maybe OverlayS) -- ^ If not Nothing, the overlay is displayed with this state
, urlEditor :: !(Editor String AppR) -- ^ text entry for URL to request
, lastResponse :: !Image -- ^ Either the response body, or an error message
, useDefaultHeaders :: !Bool -- ^ If False, replace with; otherwise append custom headers
, customHeaders :: ![(Bool, Header)] -- ^ additional/replacement request headers, and active flag
, headerEditor :: !(Maybe (Editor Text AppR)) -- ^ When a custom header name or value is being edited, non-Nothing
, payload :: !(Maybe Lazy.ByteString) -- ^ just the request body, no content type / filename
, connManager :: !HC.Manager -- ^ HTTP connection manager
}
{-|
State of the UI overlay, which is currently just the "pop-up" for the method selector.
-}
data OverlayS = OverlayS
{ methodEditorExtent :: Extent AppR -- ^ Where the pop-up should start
, methodList :: List AppR Method -- ^ Method selection
}
-- | Application Resource Name — identifies every named widget in the Brick widget tree.
data AppR
= MethodEditor -- ^ The single-line editor for the HTTP method string.
| UrlEditor -- ^ The single-line editor for the target URL.
| DefaultHeadersToggle -- ^ The checkbox-like widget for toggling default header use.
| ExistingCustomHeader CustomHeaderR -- ^ One cell within the custom-headers table.
| AddCustomHeader -- ^ The @+@ button that creates a new custom header row.
| ResponseBodyView -- ^ The scrollable viewport that shows the response body.
| MethodSelector -- ^ The pop-up list used to pick an HTTP method.
deriving (Eq, Ord, Show)
{-|
Resource name for a single cell in the custom-headers table.
'listIndex' selects the row (0-based index into 'customHeaders' of 'AppS') and 'column'
selects which of the three cells in that row has focus.
-}
data CustomHeaderR = MkCustomHeaderR
{ listIndex :: !Int -- ^ target in 'customHeaders' from 'AppS'
, column :: !CustomHeaderColumn
}
deriving (Eq, Ord, Show)
-- | Which column of a custom-header row has focus.
data CustomHeaderColumn
= ActiveToggle -- ^ The enabled/disabled checkbox column.
| NameEditor -- ^ The header-name editor column.
| ValueEditor -- ^ The header-value editor column.
deriving (Eq, Ord, Show)
-- | Alignment of one range strictly within another range both over a discete, totally ordered set.
data RangeInAlign
= Min -- ^ min of both ranges match
| MidL -- ^ inner midpoint as close as possible to, but less than or equal to outer midpoint
| MidG -- ^ inner midpoint as close as possible to, but greater than or equal to outer midpoint
| Max -- ^ max of both ranges match
deriving (Eq, Ord, Show)
-- | Vertical alignment
type VertAlign = RangeInAlign
top{-, centerHigh, centerLow, bottom-} :: VertAlign
-- | Align at the top, matching min vert corodinates.
top = Min
{-
centerHigh = MidL
centerLow = MidG
bottom = Max
-}
-- | Wide-ways ("horizonal") alignment
type WideAlign = RangeInAlign
left{-, centerLeft, centerRight, right-} :: VertAlign
-- | Align on the left, matching min wide coordinates.
left = Min
{-
centerLeft = MidL
centerRight = MidG
right = Max
-}