@@ -949,59 +949,72 @@ replaceStrings tfrom tto ts =
949949
950950 let
951951 -- 2021-02-18: NOTE: if there is no match - the process does not changes the context, simply slides along the string.
952- -- So it should be more effective to pass the context as the first argument.
952+ -- So it isbe more effective to pass the context as the first argument.
953953 -- And moreover, the `passOneCharNgo` passively passes the context, to context can be removed from it and inherited directly.
954954 -- Then the solution would've been elegant, but the Nix bug prevents elegant implementation.
955- go input output ctx =
955+ go ctx input output =
956956 case maybePrefixMatch of
957957 Nothing ->
958- -- Pass the chars until match
959- passOneCharNgo input output ctx
958+ -- Passively pass the chars
959+ realPassOneChar
960+
960961 Just (matched, replacementNS, unprocessedInput) ->
961962 sendReplaceToOutput
962963
963964 where
964- sendReplaceToOutput = withNixBug unprocessedInput updatedOutput updatedCtx
965- withNixBug =
965+ sendReplaceToOutput = sendReplaceToOutputWithNixBug unprocessedInput updatedOutput
966+ sendReplaceToOutputWithNixBug =
966967 bool
967- go
968-
969968 -- Allowing match on "" is a inherited bug of Nix,
970969 -- when "" is checked - it always matches. And so - when it checks - it always insers a replacement, and then process simply passesthrough the char that was under match.
971970 --
972971 -- repl> builtins.replaceStrings ["" "e"] [" " "i"] "Hello world"
973972 -- " H e l l o w o r l d "
974973 -- repl> builtins.replaceStrings ["ll" ""] [" " "i"] "Hello world"
975974 -- "iHie ioi iwioirilidi"
976- passOneCharNgo
977- (matched == mempty )
975+ (go updatedCtx) -- true tail recursion
976+ bugPassOneChar -- augmented recursion
977+ isNixBugCase
978+
979+ isNixBugCase = matched == mempty
978980
979981 updatedOutput = output <> replacement
980982 replacement = Builder. fromText $ stringIgnoreContext replacementNS
981983
982984 updatedCtx = ctx <> replacementCtx
983985 replacementCtx = NixString. getContext replacementNS
984986
987+ -- The bug modifies the content, so need to pass modified args => bug demands `pass` to be a real function =>
988+ -- `go` calls `pass` function
989+ -- `pass` calls `go` function
990+ -- In other words, bug creates a case of mutual recusion.
991+ bugPassOneChar input output =
992+ maybe
993+ (finish updatedCtx output) -- The base case - there is no chars left to process -> finish
994+ (\ (c, i) -> go updatedCtx i (output <> Builder. singleton c)) -- If there are chars - pass one char & continue
995+ (Text. uncons input) -- chip first char
985996 where
986997 -- When prefix matched something - returns (match, replacement, reminder)
987998 maybePrefixMatch :: Maybe (Text , NixString , Text )
988999 maybePrefixMatch = formMatchReplaceTailInfo <$> find ((`Text.isPrefixOf` input) . fst ) fromKeysToValsMap
1000+ where
1001+ formMatchReplaceTailInfo = (\ (m, r) -> (m, r, Text. drop (Text. length m) input))
9891002
990- formMatchReplaceTailInfo = ( \ (m, r) -> (m, r, Text. drop ( Text. length m) input))
1003+ fromKeysToValsMap = zip ( fmap stringIgnoreContext fromKeys) toVals
9911004
992- fromKeysToValsMap = zip (fmap stringIgnoreContext fromKeys) toVals
993-
994- passOneCharNgo input output =
1005+ -- Not passing args => It is constant that gets embedded into `go` => It is simple `go` tail recursion
1006+ realPassOneChar =
9951007 maybe
996- (finish output) -- The base case - there is no chars left to process -> finish
997- (\ (c, t ) -> go t (output <> Builder. singleton c)) -- If there are chars - pass one char & continue
1008+ (finish ctx output) -- The base case - there is no chars left to process -> finish
1009+ (\ (c, i ) -> go ctx i (output <> Builder. singleton c)) -- If there are chars - pass one char & continue
9981010 (Text. uncons input) -- chip first char
9991011
1012+
10001013 -- 2021-02-18: NOTE: rly?: toStrict . toLazyText
10011014 -- Maybe `text-builder`, `text-show`?
1002- finish = makeNixString . LazyText. toStrict . Builder. toLazyText
1015+ finish ctx output = makeNixString ( LazyText. toStrict $ Builder. toLazyText output) ctx
10031016
1004- toValue $ go (stringIgnoreContext string) mempty $ NixString. getContext string
1017+ toValue $ go (NixString. getContext string) (stringIgnoreContext string) mempty
10051018
10061019removeAttrs
10071020 :: forall e t f m
0 commit comments