css-parser-0.0.1: src/CssParser/Show.hs
{-# LANGUAGE RequiredTypeArguments #-}
{-# LANGUAGE UndecidableInstances #-}
module CssParser.Show
( module X
, CssShow (..)
, ShowSpaceBetween (..)
, ShowParenthesis (..)
, Embraced (..)
, Encurled (..)
, CslNe (..)
, SslNe (..)
, Csl (..)
, mayCss
, mkDecodingMap
, mkDecodingMap'
, smartLookup
, toCssStr
) where
import CssParser.Prelude
import CssParser.TextMarshal as X
import Data.HashMap.Strict qualified as HM
import Data.Text qualified as T
class ShowSpaceBetween (a :: Type) (b :: Type) where
cssSpace :: forall aa -> forall bb -> (aa ~ a, bb ~ b) => LText
class CssShow a where
toCssText :: a -> LText
instance (ShowSpaceBetween a a, CssShow a) => CssShow [a] where
toCssText = intercalate (cssSpace a a) . fmap toCssText
{- HLINT ignore "Use concatMap" -}
instance (ShowSpaceBetween a a, CssShow a) => CssShow (NonEmpty a) where
toCssText = toCssText . toList
instance CssShow () where
toCssText () = " 0 ";
instance CssShow a => CssShow (Maybe a) where
toCssText = maybe "" ((<> " ") . toCssText)
instance (CssShow a, CssShow b) => CssShow (Either a b) where
toCssText = \case
Left e -> toCssText e
Right v -> toCssText v
instance (CssShow at, CssShow bt, ShowSpaceBetween at bt) => CssShow (These at bt) where
toCssText = \case
This a -> toCssText a
That b -> toCssText b
These a b -> toCssText a <> cssSpace at bt <> toCssText b
class ShowParenthesis (parent :: Type) (this :: Type) where
left :: forall pp -> forall tt -> (pp ~ parent, tt ~ this) => LText
right :: forall pp -> forall tt -> (pp ~ parent, tt ~ this) => LText
newtype Csl a = Csl [a] deriving (Show, Eq, Ord, Generic)
instance CssShow a => CssShow (Csl a) where
toCssText (Csl l) = intercalate ", " $ fmap toCssText l
newtype CslNe a = CslNe (NonEmpty a) deriving (Show, Eq, Ord, Generic)
instance CssShow a => CssShow (CslNe a) where
toCssText (CslNe l) = toCssText . Csl $ toList l
newtype SslNe a = SslNe (NonEmpty a) deriving (Show, Eq, Ord, Generic)
instance CssShow a => CssShow (SslNe a) where
toCssText (SslNe l) = unwords . fmap toCssText $ toList l
newtype Embraced a = Embraced a deriving (Show, Eq, Ord, Generic)
instance CssShow a => CssShow (Embraced a) where
toCssText (Embraced a) = "(" <> toCssText a <> ")"
newtype Encurled a = Encurled a deriving (Show, Eq, Ord, Generic)
instance CssShow a => CssShow (Encurled a) where
toCssText (Encurled a) = "{" <> toCssText a <> "}"
instance CssShow Integer where
toCssText = numToText
instance CssShow Bool where
toCssText = \case
False -> "false"
True -> "true"
mayCss :: CssShow a => (LText -> LText) -> Maybe a -> LText
mayCss f = maybe "" (f . toCssText)
mkDecodingMap :: forall a. (Enum a, Bounded a, CssShow a) => HM.HashMap Text a
mkDecodingMap = mkDecodingMap' $ enumFromTo minBound maxBound
mkDecodingMap' :: (CssShow a) => [a] -> HM.HashMap Text a
mkDecodingMap' kds = HM.fromList (zip origKeys kds <> zip lowKeys kds)
where
origKeys = toStrict . toCssText <$> kds
lowKeys = T.toLower <$> origKeys
smartLookup :: Text -> HM.HashMap Text a -> Maybe a
smartLookup k m =
case HM.lookup k m of
Nothing -> HM.lookup (T.toLower k) m
o -> o
toCssStr :: CssShow a => a -> String
toCssStr = unpack . toCssText