Repository navigation
feat(ts): translate the rest of str's searches and text iterators - #461
Merged
Merged
Conversation
Quest-Claim: 0e864306bae9d857
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated
marked this pull request as ready for review
November 2, 2026 23:33
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 59 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. CodeRabbit Verify
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
rust2-ts refused most of
str's pattern searches and text iterators as unsupported calls:find,strip_prefix,strip_suffix,trim_matches,replace,rsplit,rsplit_terminator,splitn,rsplitn,split_inclusive,matches,rmatches,rmatch_indices,char_indices,lines, andsplit_whitespace(quest, found by #434). No consumer calls them yet. They are planned as part of std.Approach
Each maps onto the runtime's
SearcherandSplitinrt/str.ts, by every pattern std takes: achar, a&stror&String, a&[char], a[char; N], and a closure.Splitgains std'sSplitInternalnext_inclusiveandnext_back_inclusive(forsplit_inclusive), andSplitNInternal's count (forsplitn).rforms (rsplit,rsplit_terminator,rsplitn,rmatches,rmatch_indices) arert.iterRevof the forward iterator, as std's are. Their clones map to{ i: { f } }.matchesis a newMatchesover theSearcher.find,strip_prefix,strip_suffix,replace, andreplacenare each one search.replaceisreplacenwith no limit, andreplacenasks for no match past its count, as std'stakedoes.trim_matchescalls a closure from the front up to the char it rejects, then from the back down to just after that char, as std'snext_rejectandnext_reject_backdo.linesissplit_inclusive('\n')mapped through std'sLinesMap.split_whitespaceissplit(char::is_whitespace)filtered to non-empty parts.char_indicesis a newCharIndicesoverChars. It counts the bytes from the back only once that end first moves.&strneedle searched from the back never moved past its first match, so it would loop. It now steps back one char between matches, as std'sEmptyNeedledoes.Choices I made without asking:
trim,trim_start, andtrim_end(std'strim_matches(char::is_whitespace)and its one-sided forms),replacen, andchar::is_whitespace. All of them use the same machinery, andsplit_whitespaceneedsrt.charIsWhitespaceanyway.split_ascii_whitespace, because std's size hint for it comes from a byte-slice split rather thanstr's. I also left out the deprecatedtrim_left_matches,trim_right_matches, andlines_any, and the unstableremainder. Each of these still refuses loudly.Tests: a new
searchesmodule in thelangfixture runs differentially against native wasm32:searches::searchesruns every search by each of the five pattern kinds. It reads each iterator from the front, from the back, or from both ends as the input bytes pick, then clones it after the first item and reads the clone from the back. The closure logs every char it is called with into aRefCell, so the output includes which chars std tests and in what order.searches::textscoverschar_indices,lines,split_whitespace, and the three trims over line ends and whitespace of every UTF-8 width. It also includes\u{200b}and\u{feff}, which are notWhite_Space(JS's\scounts\u{feff}as whitespace).caller.tscover:athat a two-char needle overlaps in;\r\n,\n\n, and a\rwith no\n;I mutated the runtime by hand 16 times. Mutations included: an inclusive part's end from either side, the count from either end, the clone's count, the
trim_matchesfloor,strip_suffixtesting the first char,lineskeeping\r, dropping U+0085 from whitespace or adding U+FEFF,char_indices' back offset,replacenone past its count,findgiving the match's end, the trailing-empty check, and the empty needle's back step. The named cases caught every one, with 2 to 760 differences each.Impact
rt.strFind,strStripPrefix,strStripSuffix,strTrimMatches,strReplace,strRsplit,strRsplitTerminator,strSplitn,strRsplitn,strSplitInclusive,strMatches,strRmatches,strRmatchIndices,strCharIndices,strLines,strSplitWhitespace, andcharIsWhitespace. Nothing breaks.Alternatives
Pattern/Searchertraits andget_uncheckedby byte offsets, which the runtime's UTF-16 strings don't have.RSplit,RSplitN, ...).rt.iterRevgives the same calls in the same order with less code.Follow-ups
None found.
Review
Codex
gpt-6.1-sol, medium effort, viaquest review --base origin/main, round 1 on head7be4c40efea473ede7bfce3bcd94e7d7adcc7996: no findings.🤖 Generated with Claude Code