Skip to content

Commit 40516d6

Browse files
committed
Nix.Builtins: replaceStrings: m refactor: readability, comments
1 parent eb51d8b commit 40516d6

File tree

1 file changed

+47
-37
lines changed

1 file changed

+47
-37
lines changed

src/Nix/Builtins.hs

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -940,47 +940,57 @@ replaceStrings
940940
-> m (NValue t f m)
941941
replaceStrings tfrom tto ts =
942942
do
943-
-- `ns*` goes for NixString here, which are with context - remember
944-
(nsFrom :: [NixString]) <- fromValue (Deeper tfrom)
945-
(nsTo :: [NixString]) <- fromValue (Deeper tto)
946-
(ns :: NixString ) <- fromValue ts
943+
-- `ns*` goes for NixString here, which are with context - remember
944+
(nsListMatch :: [NixString]) <- fromValue (Deeper tfrom)
945+
(nsListReplace :: [NixString]) <- fromValue (Deeper tto)
946+
(ns :: NixString ) <- fromValue ts
947+
948+
when (length nsListMatch /= length nsListReplace)
949+
$ throwError $ ErrorCall "builtins.replaceStrings: Arguments `from`&`to` are lists `from` what replace `to` what, so the number of their inhabitanting elements must always match."
950+
951+
let
952+
go remainder processedAccum ctx =
953+
case maybePrefixMatches nsListMatch remainder of
954+
Nothing ->
955+
process remainder processedAccum ctx
956+
Just (matched, replacementNS, rest) ->
957+
-- Allowing match on "" is a bug-quirk of Nix,
958+
-- when "" is checked - it always matches. And so - if there is no previous matches the "" is replaced with " " and the process simply passesthrough the next char.
959+
--
960+
-- repl> builtins.replaceStrings ["" "e"] [" " "i"] "Hello world"
961+
-- " H e l l o w o r l d "
962+
-- repl> builtins.replaceStrings ["ll" ""] [" " "i"] "Hello world"
963+
-- "iHie ioi iwioirilidi"
964+
(if matched == mempty then process else go) rest updProcessedAccum newCtx
947965

948-
when (length nsFrom /= length nsTo)
949-
$ throwError $ ErrorCall "builtins.replaceStrings: Arguments `from`&`to` are lists `from` what replace `to` what, so the number of their inhabitanting elements must always match."
950-
let
966+
where
967+
newReplacement = Builder.fromText $ stringIgnoreContext replacementNS
968+
updProcessedAccum = processedAccum <> newReplacement
969+
additionalCtx = NixString.getContext replacementNS
970+
newCtx = ctx <> additionalCtx
971+
972+
where
973+
process text result =
974+
maybe -- chip one char from text
975+
(finish result)
976+
(\(c, t) -> go t (result <> Builder.singleton c))
977+
(Text.uncons text)
978+
979+
finish = makeNixString . LazyText.toStrict . Builder.toLazyText
980+
981+
maybePrefixMatches nsListMatch src =
982+
do -- monadic context handles Maybe result here, aka if Nothing returned
983+
(from, to) <- find ((`Text.isPrefixOf` src) . fst) matchReplaceMap
984+
let rest = Text.drop (Text.length from) src
985+
pure (from, to, rest)
951986

952-
go source resultAccum ctx =
953-
case lookupPrefix source of
954-
Nothing ->
955-
process source resultAccum ctx
956-
Just (prefix, replacementNS, rest) ->
957-
(if prefix == mempty then process else go) rest newResultAccum newCtx
958-
where
959-
replacement = Builder.fromText $ stringIgnoreContext replacementNS
960-
newResultAccum = resultAccum <> replacement
961-
additionalCtx = NixString.getContext replacementNS
962-
newCtx = ctx <> additionalCtx
963987
where
964-
process text result =
965-
maybe
966-
(finish result)
967-
(\(h, t) -> go t (result <> Builder.singleton h))
968-
(Text.uncons text)
969-
where
970-
finish = makeNixString . LazyText.toStrict . Builder.toLazyText
971-
972-
lookupPrefix src =
973-
do -- monadic context handles Maybe result here, aka if Nothing returned
974-
(prefix, replacement) <- find ((`Text.isPrefixOf` src) . fst)
975-
$ zip from nsTo
976-
let rest = Text.drop (Text.length prefix) src
977-
pure (prefix, replacement, rest)
978-
where
979-
from = fmap stringIgnoreContext nsFrom
988+
textListMatch = fmap stringIgnoreContext nsListMatch
989+
matchReplaceMap = zip textListMatch nsListReplace
980990

981-
toValue
982-
$ go (stringIgnoreContext ns) mempty
983-
$ NixString.getContext ns
991+
toValue
992+
$ go (stringIgnoreContext ns) mempty
993+
$ NixString.getContext ns
984994

985995
removeAttrs
986996
:: forall e t f m

0 commit comments

Comments
 (0)