module Data.Config.Internal.Rename (rename) where
import Prelude hiding (null)
import Data.Text (Text, append, null)
import Data.Config.Internal.AST
import Data.Config.Internal.Pos
import Data.Config.Internal.Scoped
infixr 7 <.>
(<.>) :: Text -> Text -> Text
(<.>) a b
| null a = b
| otherwise = a `append` ("." `append` b)
rename :: [Prop AST Pos] -> [Prop AST Scoped]
rename = fmap renameProp
renameProp :: Prop AST Pos -> Prop AST Scoped
renameProp (Prop n v) = Prop n (renameAST n n v)
renameAST :: Text -> Text -> AST Pos -> AST Scoped
renameAST prop scope (AST expr pos) =
case expr of
ID i -> AST (ID i) $ Scoped prop scope pos
STRING i -> AST (STRING i) $ Scoped prop scope pos
LIST xs -> renameList prop scope xs pos
SUBST i -> AST (SUBST i) $ Scoped prop scope pos
MERGE l r -> renameMerge prop scope l r pos
OBJECT ps -> renameObject prop scope ps pos
renameList :: Text -> Text -> [AST Pos] -> Pos -> AST Scoped
renameList prop scope xs pos
= let xs' = fmap (renameAST prop "") xs in
AST (LIST xs') $ Scoped prop scope pos
renameMerge :: Text -> Text -> AST Pos -> AST Pos -> Pos -> AST Scoped
renameMerge prop scope l r pos
= let sl = renameAST prop scope l
sr = renameAST prop scope r in
AST (MERGE sl sr) $ Scoped prop scope pos
renameObject :: Text -> Text -> [Prop AST Pos] -> Pos -> AST Scoped
renameObject prop scope ps pos
= let go (Prop n v)
= let scope' = scope <.> n
v' = renameAST prop scope' v in
Prop scope' v'
ps' = fmap go ps in
AST (OBJECT ps') $ Scoped prop scope pos