-- | -- -- Module : Network.URI.Template.Internal.VarSpec -- Copyright : (c) 2025 Patrick Brisbin -- License : AGPL-3 -- Maintainer : pbrisbin@gmail.com -- Stability : experimental -- Portability : POSIX module Network.URI.Template.Internal.VarSpec ( VarSpec (..) , varSpecP , varSpecPretty , expandVarSpec ) where import Prelude import Data.Map.Strict (Map) import Data.Map.Strict qualified as Map import Data.Text (Text) import Data.Text qualified as T import Network.URI.Template.Internal.Modifier import Network.URI.Template.Internal.Operator import Network.URI.Template.Internal.Parse import Network.URI.Template.Internal.Pretty import Network.URI.Template.VarName import Network.URI.Template.VarValue data VarSpec = VarSpec { name :: VarName , modifier :: Maybe Modifier } deriving stock (Eq, Show) -- | -- -- @ -- varspec = varname [ modifier-level4 ] -- @ varSpecP :: Parser VarSpec varSpecP = VarSpec <$> varNameP <*> optional modifierP varSpecPretty :: VarSpec -> Doc Ann varSpecPretty v = annotate AnnVarName (pretty $ unVarName v.name) <> maybe mempty (annotate AnnModifier . modifierPretty) v.modifier expandVarSpec :: Map VarName VarValue -> OperatorActions -> VarSpec -> [Text] expandVarSpec vars oa vs = maybe [] renderValues $ Map.lookup vs.name vars where renderValues :: VarValue -> [Text] renderValues = \case VarNull -> [] VarValue t | Just (Prefix n) <- vs.modifier -> renderValueEsc $ T.take n t | otherwise -> renderValueEsc t VarList ts | null ts -> [] | Just Explode <- vs.modifier -> concatMap renderValueEsc ts | otherwise -> renderValueCsv $ map oa.escapeValue ts VarMap kvs | null kvs -> [] | Just Explode <- vs.modifier -> map (uncurry $ renderKeyValue '=') kvs | otherwise -> renderValueCsv $ map (uncurry $ renderKeyValue ',') kvs renderValue = pure . oa.renderValue vs.name renderValueEsc = renderValue . oa.escapeValue renderValueCsv = renderValue . T.intercalate "," renderKeyValue c k v = oa.escapeValue k <> T.singleton c <> oa.escapeValue v