clay-0.16.0: src/Clay/Grid.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ExtendedDefaultRules #-}
{-# OPTIONS_GHC -Wno-type-defaults #-}
-- | Partial implementation of
-- | <https://alligator.io/css/css-grid-layout-grid-areas grid area CSS API>.
module Clay.Grid
(
-- * Grid
--
-- $gridIntro
gridGap
, gridTemplateColumns
-- * Size and location
--
-- $sizeAndLocationIntro
-- ** Data types and type classes
, GridLine
, ToGridLine
, GridLines2
, ToGridLines2
, GridLines4
, ToGridLines4
, OneGridLine
, TwoGridLines
, ThreeGridLines
, FourGridLines
, CustomIdentGrid
, customIdentToText
, partialMkCustomIdentGrid
, ToSpan
-- ** Style properties
--
-- $invalidValues
, gridArea
, gridColumn
, gridColumnStart
, gridColumnEnd
, gridRow
, gridRowStart
, gridRowEnd
-- ** Keywords
, (//)
, span_
)
where
import qualified Clay.Common as Com
import Clay.Property (Val, Value, noCommas, value)
import Clay.Size (Size)
import Clay.Stylesheet (Css, key)
import Data.Char (isNumber)
import Data.Text (Text)
import qualified Data.Text as T
import Prelude
-- $gridIntro
-- @grid-gap@ and @grid-template@ CSS properties.
--
-- === Example
-- For the below CSS code:
--
-- @
-- .grid1 {
-- display: grid;
-- width: max-content;
-- }
--
-- .grid3 {
-- display: grid;
-- width: max-content;
-- }
--
-- \@media (min-width: 40.0rem) {
-- .grid3 {
-- display: grid;
-- grid-template-columns: 1fr 1fr 1fr;
-- grid-gap: 1rem;
-- width: max-content;
-- }
-- }
-- @
--
-- The corresponding clay code is:
--
-- @
-- ".grid1" ? do
-- display grid
-- width maxContent
-- ".grid3" ? do
-- display grid
-- width maxContent
-- query M.screen [M.minWidth (rem 40)] $ ".grid3" ? do
-- display grid
-- gridTemplateColumns [fr 1, fr 1, fr 1]
-- gridGap $ rem 1
-- width maxContent
-- @
-- | Property sets the gaps (gutters) between rows and columns.
gridGap :: Size a -> Css
gridGap = key "grid-gap"
-- | Property defines the line names and track sizing functions of the grid columns.
gridTemplateColumns :: [Size a] -> Css
gridTemplateColumns = key "grid-template-columns" . noCommas
-- $sizeAndLocationIntro
--
-- == CSS documentation
-- The below functions are based on
-- [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/CSS)
-- CSS documentation.
--
-- === __Naming note__
-- In this documentation, as the functions are polymorphic we sometimes
-- refer to the CSS types as used in the
-- [mdm web docs_](https://developer.mozilla.org/en-US/docs/Web/CSS)
-- rather than the Haskell types.
-- For example, @grid-line@ is used instead of 'GridLine' as a the argument
-- might be provided as a 'GridLine' but also as an 'Integer', 'String', etc.
--
-- == Pragma
-- #pragma#
-- If you want to avoid specifying the types of the arguments, enable
-- the @ExtendedDefaultRules@ GHC language pragma as well as the
-- @-Wno-type-defaults@ GHC option to avoid compilation warnings.
--
-- @
-- {-# LANGUAGE ExtendedDefaultRules #-}
-- {-# OPTIONS_GHC -Wno-type-defaults #-}
-- @
--
-- === __Examples__
-- With the above enabled, you can write:
--
-- >> gridRowStart 2
--
-- >> gridRowStart "somegridarea"
--
-- If you do not enable those, then you must write:
--
-- >> gridRowStart (2 :: Integer)
--
-- >> gridRowStart ("somegridarea" :: String)
--
-- === __Note__
-- If you decide to enable the above, it is advisable to have your Clay
-- CSS code in its own module, so the behaviour of the rest of your code
-- is not affected.
--
-- == Examples
-- Examples are provided through the documentation for the various functions.
-- Further examples can be found in the source code of the test suite
-- in the GridSpec.hs module.
-- | A @grid-line@ value.
--
-- A @grid-line@ value specifies a size and location in a grid.
--
-- === __Note__
-- To know more about @grid-line@ value, see for example the documentation of
-- the [grid-row-start](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-row-start)
-- CSS property.
data GridLine
-- | 'Integer' value.
--
-- __NOTE:__ 'Integer' value of 0 is invalid.
= Coordinate Integer
-- | @custom-ident@ with an optional 'Integer' value.
--
-- __NOTE:__ 'Integer' value of 0 is invalid.
| GridLineCustomIdent CustomIdentGrid (Maybe Integer)
-- | @span@ CSS keyword with an optional @custom-ident@
-- | and/or 'Integer' value.
--
-- __NOTE:__ negative 'Integer' or 0 are invalid.
| Span (Maybe CustomIdentGrid) (Maybe Integer)
-- | Other grid line values: @auto@, @inherit@, @initial@, @unset@.
| OtherGridLine Value
deriving (Eq, Show)
class ToGridLine a where
-- | Convert the provided type to a 'GridLine'.
toGridLine :: a -> GridLine
instance ToGridLine GridLine where
toGridLine = id
instance ToGridLine Integer where
-- | __NOTE:__ 'Integer' value of 0 is invalid.
toGridLine = Coordinate
-- | @custom-ident@ value.
instance ToGridLine CustomIdentGrid where
toGridLine x = GridLineCustomIdent x Nothing
-- | @custom-ident@ value.
instance ToGridLine String where
toGridLine = toGridLine . partialMkCustomIdentGrid . T.pack
-- | Both @custom-ident@ and `Integer` values, provided as a pair.
--
-- __NOTE:__ 'Integer' value of 0 is invalid.
instance ToGridLine (CustomIdentGrid, Integer) where
toGridLine (x, y) = GridLineCustomIdent x (Just y)
-- | Both @custom-ident@ and `Integer` values, provided as a pair.
--
-- __NOTE:__ 'Integer' value of 0 is invalid.
instance ToGridLine (String, Integer) where
toGridLine (x, y) = toGridLine (partialMkCustomIdentGrid $ T.pack x, y)
-- | One or two @grid-line@ values.
data GridLines2
-- | One @grid-line@ value.
= One2 OneGridLine
-- | Two @grid-line@ values.
| Two2 TwoGridLines
class ToGridLines2 a where
-- | Convert the provided type to 'GridLines2' (one or two @grid-line@ values).
toGridLines2 :: a -> GridLines2
-- | One @grid-line@ value.
instance ToGridLines2 GridLine where
toGridLines2 = One2 . OneGridLine
-- | One @grid-line@ value.
instance ToGridLines2 OneGridLine where
toGridLines2 = One2
-- | Two @grid-line@ values.
instance ToGridLines2 TwoGridLines where
toGridLines2 = Two2
-- | One or two @grid-line@ values.
instance ToGridLines2 GridLines2 where
toGridLines2 = id
-- | One 'Integer' value.
--
-- __NOTE:__ 'Integer' value of 0 is invalid.
instance ToGridLines2 Integer where
toGridLines2 = toGridLines2 . toGridLine
-- | One @custom-ident@ value.
instance ToGridLines2 CustomIdentGrid where
toGridLines2 = toGridLines2 . toGridLine
-- | One @custom-ident@ value.
instance ToGridLines2 String where
toGridLines2 = toGridLines2 . toGridLine
-- | One time both a @custom-ident@ and 'Integer' values, provided as a pair.
--
-- __NOTE:__ 'Integer' value of 0 is invalid.
instance ToGridLines2 (CustomIdentGrid, Integer) where
toGridLines2 = toGridLines2 . toGridLine
-- | One time both a @custom-ident@ and 'Integer' values, provided as a pair.
--
-- __NOTE:__ 'Integer' value of 0 is invalid.
instance ToGridLines2 (String, Integer) where
toGridLines2 = toGridLines2 . toGridLine
-- | One, two, three or four @grid-line@ values.
data GridLines4
-- | One @grid-line@ value.
= One4 OneGridLine
-- | Two @grid-line@ values.
| Two4 TwoGridLines
-- | Three @grid-line@ values.
| Three4 ThreeGridLines
-- | Four @grid-line@ values.
| Four4 FourGridLines
class ToGridLines4 a where
-- | Convert the provided type to 'GridLines4'
-- (one, two, three or four @grid-line@ values).
toGridLines4 :: a -> GridLines4
-- | One @grid-line@ value.
instance ToGridLines4 GridLine where
toGridLines4 = One4 . OneGridLine
-- | One @grid-line@ value.
instance ToGridLines4 OneGridLine where
toGridLines4 = One4
-- | Two @grid-line@ values.
instance ToGridLines4 TwoGridLines where
toGridLines4 = Two4
-- | Three @grid-line@ values.
instance ToGridLines4 ThreeGridLines where
toGridLines4 = Three4
-- | Four @grid-line@ values.
instance ToGridLines4 FourGridLines where
toGridLines4 = Four4
-- | One, two, three or four @grid-line@ values.
instance ToGridLines4 GridLines4 where
toGridLines4 = id
-- | One 'Integer' value.
--
-- __NOTE:__ 'Integer' value of 0 is invalid.
instance ToGridLines4 Integer where
toGridLines4 = toGridLines4 . toGridLine
-- | One @custom-ident@ value.
instance ToGridLines4 CustomIdentGrid where
toGridLines4 = toGridLines4 . toGridLine
-- | One @custom-ident@ value.
instance ToGridLines4 String where
toGridLines4 = toGridLines4 . toGridLine
-- | One time both a @custom-ident@ and 'Integer' values, provided as a pair.
--
-- __NOTE:__ 'Integer' value of 0 is invalid.
instance ToGridLines4 (CustomIdentGrid, Integer) where
toGridLines4 = toGridLines4 . toGridLine
-- | One time both a @custom-ident@ and 'Integer' values, provided as a pair.
--
-- __NOTE:__ 'Integer' value of 0 is invalid.
instance ToGridLines4 (String, Integer) where
toGridLines4 = toGridLines4 . toGridLine
-- | One 'GridLine' value.
newtype OneGridLine = OneGridLine GridLine
-- | Two 'GridLine' values.
data TwoGridLines = TwoGridLines GridLine GridLine
-- | Three 'GridLine' values.
data ThreeGridLines = ThreeGridLines GridLine GridLine GridLine
-- | Four 'GridLine' values.
data FourGridLines = FourGridLines GridLine GridLine GridLine GridLine
-- | CSS @custom-ident@.
--
-- The data constructor is not exported. Use the 'partialMkCustomIdentGrid'
-- smart constructor to create a 'CustomIdentGrid'.
--
-- === __Note__
-- In CSS, some values for @custom-ident@ are invalid depending on the CSS
-- property the @custom-ident@ is used with.
-- Consequently, the @custom-ident@ is only for CSS grid.
newtype CustomIdentGrid = CustomIdentGrid Text deriving (Eq, Ord, Read, Show)
-- | Convert a 'CustomIdentGrid' to 'Text'.
--
-- === __Note__
-- The function is defined on its own as the newtype constructor
-- of 'CustomIdentGrid'is not exported.
customIdentToText :: CustomIdentGrid -> Text
customIdentToText (CustomIdentGrid x) = x
-- | Create a 'CustomIdentGrid'.
--
-- __WARNING__: this function is partial. An error will be raised if:
--
-- * "span" is provided as a value (this is a reserved keyword in this context)
-- * a number is provided as first character
-- * __If__ a hyphen (-) is provided as first character:
--
-- ** a number is provided as second character
-- ** a hyphen (-) is provided as second character.
--
-- === __Note__
-- The above is a partial implementation of the CSS custom-ident naming rules.
-- If you stick to the following charset @[a-zA-z0-9-_]@ the checks will be effective
-- and your CSS custom-ident will be a valid one.
-- On the other hand, the following will not be checked:
--
-- * character escaping (for example @\?@) or unicode
-- * characters provided as hexadecimal number (for example @\0x03BB@)
-- * characters outside of the above charset.
--
-- More information regarding this topic can be found on
-- [mdm web docs_](https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident)
partialMkCustomIdentGrid :: Text -> CustomIdentGrid
partialMkCustomIdentGrid "span" = error "Custom-ident for a grid property cannot be named span"
partialMkCustomIdentGrid txt = checkText
where
checkText = checkHead (fst unconsTxt)
checkHead :: Char -> CustomIdentGrid
checkHead c
| isNumber c = error "Custom-ident cannot start with a number"
| c == '-' = checkSecond second
| otherwise = CustomIdentGrid txt
checkSecond (Just s)
| s == '-' =
error "Custom-ident cannot start with two hyphens"
| isNumber s =
error "Custom-ident cannot start with a hyphen followed by a number"
| otherwise = CustomIdentGrid txt
checkSecond Nothing = CustomIdentGrid txt
unconsTxt = case T.uncons txt of
Nothing -> error "Custom-ident cannot be empty"
Just (f, r) -> (f, r)
second :: Maybe Char
second = fst <$> T.uncons (snd unconsTxt)
-- $invalidValues
--
-- #partial#
-- The below functions are partial. They will raise an error if
-- provided with a @grid-line@ value which is:
--
-- * an 'Integer' value of 0
-- * a pair with an 'Integer' component of value 0
-- * a 'span_' function provided with an 'Integer' value of 0 or negative
-- * a 'span_' function provided with a pair value with
-- an 'Integer' component of 0 or negative.
-- * an invalid @custom-ident@ value, see 'partialMkCustomIdentGrid'.
-- | Property shorthand specifies a grid item's size and location
-- within a grid.
--
-- One to four @grid-line@ values can be specified.
-- Grid-line values must be separated by a '(//)' operator.
--
-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".
--
-- ==== __Examples__
--
-- The below examples assume that the @ExtendedDefaultRules@ GHC language
-- pragma is enabled. See above "Clay.Grid#pragma".
--
-- > gridArea (auto :: GridLine)
--
-- > gridArea "somegridarea"
--
-- > gridArea $ ("somegridarea", 4) // ("someothergridarea", 2)
--
-- > gridArea $ 1 // 3 // 4
gridArea :: ToGridLines4 a => a -> Css
gridArea x = key "grid-area" (partialToGridLines4 x)
-- | Property shorthand specifies a grid item's size and location
-- within a grid column.
--
-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".
--
-- ==== __Examples__
--
-- The below examples assume that the @ExtendedDefaultRules@ GHC language
-- pragma is enabled. See above "Clay.Grid#pragma".
--
-- > gridColumn (auto :: GridLine)
--
-- > gridColumn $ span_ 3
--
-- > gridColumn $ span_ ("somegridarea", 5)
--
-- > gridColumn $ span_ 3 // 6
gridColumn :: ToGridLines2 a => a -> Css
gridColumn x = key "grid-column" (partialToGridLines2 x)
-- | Property specifies a grid item's start position within the grid column.
--
-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".
--
-- ==== __Examples__
--
-- The below examples assume that the @ExtendedDefaultRules@ GHC language
-- pragma is enabled. See above "Clay.Grid#pragma".
--
-- > gridColumnStart (inherit :: GridLine)
--
-- > gridColumnStart 2
--
-- > gridColumnStart ("somegridarea", 4)
--
-- > gridColumnStart $ span_ ("somegridarea", 5)
gridColumnStart :: ToGridLine a => a -> Css
gridColumnStart x = key "grid-column-start" (partialToGridLine x)
-- | Property specifies a grid item's end position within the grid column.
--
-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".
--
-- ==== __Examples__
--
-- The below examples assume that the @ExtendedDefaultRules@ GHC language
-- pragma is enabled. See above "Clay.Grid#pragma".
--
-- > gridColumnEnd (initial :: GridLine)
--
-- > gridColumnEnd 2
--
-- > gridColumnEnd "somegridarea"
--
-- > gridColumnEnd $ span_ "somegridarea"
gridColumnEnd :: ToGridLine a => a -> Css
gridColumnEnd x = key "grid-column-end" (partialToGridLine x)
-- | Property shorthand specifies a grid item's size and location
-- within a grid row.
--
-- One or two @grid-line@ values can be specified.
-- @grid-line@ values must be separated by a '(//)' operator.
--
-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".
--
-- ==== __Examples__
--
-- The below examples assume that the @ExtendedDefaultRules@ GHC language
-- pragma is enabled. See above "Clay.Grid#pragma".
--
-- > gridRow (unset :: GridLine)
--
-- > gridRow $ span_ 3
--
-- > gridRow $ span_ 3 // 6
--
-- > gridRow $ span_ ("somegridarea", 5) // span_ 2
gridRow :: ToGridLines2 a => a -> Css
gridRow x = key "grid-row" (partialToGridLines2 x)
-- | Property specifies a grid item's start position within the grid row.
--
-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".
--
-- ==== __Examples__
--
-- The below examples assume that the @ExtendedDefaultRules@ GHC language
-- pragma is enabled. See above "Clay.Grid#pragma".
--
-- > gridRowStart (initial :: GridLine)
--
-- > gridRowStart (-2)
--
-- > gridRowStart $ span_ "somegridarea"
--
-- > gridRowStart "somegridarea"
gridRowStart :: ToGridLine a => a -> Css
gridRowStart x = key "grid-row-start" (partialToGridLine x)
-- | Property specifies a grid item's end position within the grid row.
--
-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".
--
-- ==== __Examples__
--
-- The below examples assume that the @ExtendedDefaultRules@ GHC language
-- pragma is enabled. See above "Clay.Grid#pragma".
--
-- > gridRowEnd (auto :: GridLine)
--
-- > gridRowEnd (-2)
--
-- > gridRowEnd ("somegridarea", 4)
--
-- > gridRowEnd $ span_ 3
gridRowEnd :: ToGridLine a => a -> Css
gridRowEnd x = key "grid-row-end" (partialToGridLine x)
class Slash a r | a -> r where
-- | `/` CSS operator.
-- Separates @grid-line@ values.
(//) :: ToGridLine b => a -> b -> r
instance Slash GridLine TwoGridLines where
x // y = TwoGridLines x (toGridLine y)
instance Slash Integer TwoGridLines where
x // y = TwoGridLines (toGridLine x) (toGridLine y)
instance Slash CustomIdentGrid TwoGridLines where
x // y = TwoGridLines (toGridLine x) (toGridLine y)
instance Slash String TwoGridLines where
x // y = TwoGridLines (toGridLine x) (toGridLine y)
instance Slash (CustomIdentGrid, Integer) TwoGridLines where
x // y = TwoGridLines (toGridLine x) (toGridLine y)
instance Slash (String, Integer) TwoGridLines where
x // y = TwoGridLines (toGridLine x) (toGridLine y)
instance Slash TwoGridLines ThreeGridLines where
(TwoGridLines xx xy) // y = ThreeGridLines xx xy (toGridLine y)
instance Slash ThreeGridLines FourGridLines where
(ThreeGridLines xx xy xz) // y = FourGridLines xx xy xz (toGridLine y)
class ToSpan a where
-- | @span@ CSS keyword, contributes to the grid item's placement.
span_ :: a -> GridLine
-- | Contributes the nth grid line to the grid item's placement.
--
-- __NOTE:__ negative 'Integer' or 0 values are invalid.
instance ToSpan Integer where
span_ x = Span Nothing (Just x)
-- | One line from the provided name is counted.
instance ToSpan String where
span_ x = Span (Just . partialMkCustomIdentGrid $ T.pack x) Nothing
-- | Nth lines from the provided name are counted.
--
-- __NOTE:__ negative 'Integer' or 0 values are invalid.
instance ToSpan (String, Integer) where
span_ (x, y) = Span (Just . partialMkCustomIdentGrid $ T.pack x) (Just y)
-- | Keyword indicating that the property contributes nothing
-- to the grid item's placement.
instance Com.Auto GridLine where
auto = OtherGridLine $ value ("auto" :: Text)
-- | Keyword `inherit` applied to a 'GridLine'.
instance Com.Inherit GridLine where
inherit = OtherGridLine $ value ("inherit" :: Text)
-- | Keyword `initial` applied to a 'GridLine'.
instance Com.Initial GridLine where
initial = OtherGridLine $ value ("initial" :: Text)
-- | Keyword `unset` applied to a 'GridLine'.
instance Com.Unset GridLine where
unset = OtherGridLine $ value ("unset" :: Text)
-- | Convertion of 'GridLine' to 'Clay.Property.Value'.
instance Val GridLine where
value (OtherGridLine val) = val
value (Coordinate x) = value x
value (GridLineCustomIdent x y) =
value $ customIdentToText x <> foldMap ((" " <>) . tshow) y
value (Span x y) =
value $ "span" <> foldMap ((" " <>)
. customIdentToText) x <> foldMap ((" " <>) . tshow) y
instance Val OneGridLine where
value (OneGridLine x) = value x
instance Val TwoGridLines where
value (TwoGridLines x y) =
value x <> value (" / " :: Text) <> value y
instance Val ThreeGridLines where
value (ThreeGridLines x y z) =
value x
<> value (" / " :: Text) <> value y
<> value (" / " :: Text) <> value z
instance Val FourGridLines where
value (FourGridLines xx xy xz yx) =
value xx
<> value (" / " :: Text) <> value xy
<> value (" / " :: Text) <> value xz
<> value (" / " :: Text) <> value yx
instance Val GridLines2 where
value (One2 x) = value x
value (Two2 x) = value x
instance Val GridLines4 where
value (One4 x) = value x
value (Two4 x) = value x
value (Three4 x) = value x
value (Four4 x) = value x
-- | Private partial function checking a 'GridLine'.
--
-- An error is raised when:
-- - An 'Integer' value of 0 is provided.
-- - A negative 'Integer' value is provided for a 'Span' constructor.
--
-- Otherwise, the initially provided 'GridLine' value is returned.
partialCheckGridLine :: GridLine -> GridLine
partialCheckGridLine gridLine = case gridLine of
Coordinate 0 -> errorValue 0
GridLineCustomIdent _ (Just 0) -> errorValue 0
s@(Span _ (Just n)) -> if n < 1
then errorValue n
else s
_ -> gridLine
where
errorValue n = error ("Value " ++ show n ++ " is invalid")
-- | Private partial function checking 'OneGridLine'.
--
-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.
partialCheckOneGridLine :: OneGridLine -> OneGridLine
partialCheckOneGridLine (OneGridLine gridLine) =
OneGridLine (partialCheckGridLine gridLine)
-- | Private partial function checking 'TwoGridLines'.
--
-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.
partialCheckTwoGridLines :: TwoGridLines -> TwoGridLines
partialCheckTwoGridLines (TwoGridLines gridLine1 gridLine2) =
TwoGridLines (partialCheckGridLine gridLine1) (partialCheckGridLine gridLine2)
-- | Private partial function checking 'ThreeGridLines'.
--
-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.
partialCheckThreeGridLines :: ThreeGridLines -> ThreeGridLines
partialCheckThreeGridLines (ThreeGridLines gridLine1 gridLine2 gridLine3) =
ThreeGridLines
(partialCheckGridLine gridLine1)
(partialCheckGridLine gridLine2)
(partialCheckGridLine gridLine3)
-- | Private partial function checking 'FourGridLines'.
--
-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.
partialCheckFourGridLines :: FourGridLines -> FourGridLines
partialCheckFourGridLines
(FourGridLines gridLine1 gridLine2 gridLine3 gridLine4) =
FourGridLines
(partialCheckGridLine gridLine1)
(partialCheckGridLine gridLine2)
(partialCheckGridLine gridLine3)
(partialCheckGridLine gridLine4)
-- | Private partial function converting its argument to 'GridLine'.
--
-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.
partialToGridLine :: ToGridLine a => a -> GridLine
partialToGridLine = partialCheckGridLine . toGridLine
-- | Private partial function converting its argument to 'GridLines2'.
--
-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.
partialToGridLines2 :: ToGridLines2 a => a -> GridLines2
partialToGridLines2 x = partialGridLine' gridLines
where
gridLines = toGridLines2 x
partialGridLine' (One2 gl) = One2 (partialCheckOneGridLine gl)
partialGridLine' (Two2 gl) = Two2 (partialCheckTwoGridLines gl)
-- | Private partial function converting its argument to 'GridLines4'.
--
-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.
partialToGridLines4 :: ToGridLines4 a => a -> GridLines4
partialToGridLines4 x = partialGridLine' gridLines
where
gridLines = toGridLines4 x
partialGridLine' (One4 gl) = One4 (partialCheckOneGridLine gl)
partialGridLine' (Two4 gl) = Two4 (partialCheckTwoGridLines gl)
partialGridLine' (Three4 gl) = Three4 (partialCheckThreeGridLines gl)
partialGridLine' (Four4 gl) = Four4 (partialCheckFourGridLines gl)
-- | Private utility function to show 'Text' instead of 'String'.
tshow :: Show a => a -> Text
tshow = T.pack . show