Make all string.index functions return ?int
parent
3f1e232c9b
commit
f1873908ea
|
|
@ -570,16 +570,16 @@ fn get_all_modules() []string {
|
|||
mut start_token := '<a href="/mod'
|
||||
end_token := '</a>'
|
||||
// get the start index of the module entry
|
||||
mut start_index := s.index_after(start_token, read_len)
|
||||
mut start_index := s.index_after(start_token, read_len) or { -1 }
|
||||
if start_index == -1 {
|
||||
break
|
||||
}
|
||||
// get the index of the end of anchor (a) opening tag
|
||||
// we use the previous start_index to make sure we are getting a module and not just a random 'a' tag
|
||||
start_token = '">'
|
||||
start_index = s.index_after(start_token, start_index) + start_token.len
|
||||
start_index = s.index_after(start_token, start_index) or { -1 } + start_token.len
|
||||
// get the index of the end of module entry
|
||||
end_index := s.index_after(end_token, start_index)
|
||||
end_index := s.index_after(end_token, start_index) or { -1 }
|
||||
if end_index == -1 {
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ fn main() {
|
|||
html := http.get_text('https://news.ycombinator.com')
|
||||
mut pos := 0
|
||||
for {
|
||||
pos = html.index_after('https://', pos + 1)
|
||||
pos = html.index_after('https://', pos + 1) or { -1 }
|
||||
if pos == -1 {
|
||||
break
|
||||
}
|
||||
end := html.index_after('"', pos)
|
||||
end := html.index_after('"', pos) or { html.len }
|
||||
println(html[pos..end])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -319,11 +319,11 @@ pub fn (a string) clone() string {
|
|||
|
||||
// replace_once replaces the first occurence of `rep` with the string passed in `with`.
|
||||
pub fn (s string) replace_once(rep string, with string) string {
|
||||
idx := s.index_(rep)
|
||||
if idx == -1 {
|
||||
if idx := s.index(rep) {
|
||||
return s.substr(0, idx) + with + s.substr(idx + rep.len, s.len)
|
||||
} else {
|
||||
return s.clone()
|
||||
}
|
||||
return s.substr(0, idx) + with + s.substr(idx + rep.len, s.len)
|
||||
}
|
||||
|
||||
// replace replaces all occurences of `rep` with the string passed in `with`.
|
||||
|
|
@ -343,10 +343,7 @@ pub fn (s string) replace(rep string, with string) string {
|
|||
}
|
||||
mut idx := 0
|
||||
for {
|
||||
idx = s.index_after(rep, idx)
|
||||
if idx == -1 {
|
||||
break
|
||||
}
|
||||
idx = s.index_after(rep, idx) or { break }
|
||||
idxs << idx
|
||||
idx += rep.len
|
||||
}
|
||||
|
|
@ -419,7 +416,7 @@ pub fn (s string) replace_each(vals []string) string {
|
|||
with := vals[rep_i + 1]
|
||||
|
||||
for {
|
||||
idx = s_.index_after(rep, idx)
|
||||
idx = s_.index_after(rep, idx) or { -1 }
|
||||
if idx == -1 {
|
||||
break
|
||||
}
|
||||
|
|
@ -899,11 +896,11 @@ pub fn (s string) substr_ni(_start int, _end int) string {
|
|||
}
|
||||
|
||||
// index returns the position of the first character of the input string.
|
||||
// It will return `-1` if the input string can't be found.
|
||||
// It will return `none` if the input string can't be found.
|
||||
[direct_array_access]
|
||||
fn (s string) index_(p string) int {
|
||||
pub fn (s string) index(p string) ?int {
|
||||
if p.len > s.len || p.len == 0 {
|
||||
return -1
|
||||
return none
|
||||
}
|
||||
if p.len > 2 {
|
||||
return s.index_kmp(p)
|
||||
|
|
@ -919,24 +916,14 @@ fn (s string) index_(p string) int {
|
|||
}
|
||||
i++
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// index returns the position of the first character of the input string.
|
||||
// It will return `none` if the input string can't be found.
|
||||
pub fn (s string) index(p string) ?int {
|
||||
idx := s.index_(p)
|
||||
if idx == -1 {
|
||||
return none
|
||||
}
|
||||
return idx
|
||||
return none
|
||||
}
|
||||
|
||||
// index_kmp does KMP search.
|
||||
[direct_array_access; manualfree]
|
||||
fn (s string) index_kmp(p string) int {
|
||||
fn (s string) index_kmp(p string) ?int {
|
||||
if p.len > s.len {
|
||||
return -1
|
||||
return none
|
||||
}
|
||||
mut prefix := []int{len: p.len}
|
||||
defer {
|
||||
|
|
@ -964,11 +951,11 @@ fn (s string) index_kmp(p string) int {
|
|||
return i - p.len + 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
return none
|
||||
}
|
||||
|
||||
// index_any returns the position of any of the characters in the input string - if found.
|
||||
pub fn (s string) index_any(chars string) int {
|
||||
pub fn (s string) index_any(chars string) ?int {
|
||||
for i, ss in s {
|
||||
for c in chars {
|
||||
if c == ss {
|
||||
|
|
@ -976,14 +963,14 @@ pub fn (s string) index_any(chars string) int {
|
|||
}
|
||||
}
|
||||
}
|
||||
return -1
|
||||
return none
|
||||
}
|
||||
|
||||
// last_index returns the position of the last occurence of the input string.
|
||||
[direct_array_access]
|
||||
fn (s string) last_index_(p string) int {
|
||||
pub fn (s string) last_index(p string) ?int {
|
||||
if p.len > s.len || p.len == 0 {
|
||||
return -1
|
||||
return none
|
||||
}
|
||||
mut i := s.len - p.len
|
||||
for i >= 0 {
|
||||
|
|
@ -996,30 +983,21 @@ fn (s string) last_index_(p string) int {
|
|||
}
|
||||
i--
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// last_index returns the position of the last occurence of the input string.
|
||||
pub fn (s string) last_index(p string) ?int {
|
||||
idx := s.last_index_(p)
|
||||
if idx == -1 {
|
||||
return none
|
||||
}
|
||||
return idx
|
||||
return none
|
||||
}
|
||||
|
||||
// index_after returns the position of the input string, starting search from `start` position.
|
||||
[direct_array_access]
|
||||
pub fn (s string) index_after(p string, start int) int {
|
||||
pub fn (s string) index_after(p string, start int) ?int {
|
||||
if p.len > s.len {
|
||||
return -1
|
||||
return none
|
||||
}
|
||||
mut strt := start
|
||||
if start < 0 {
|
||||
strt = 0
|
||||
}
|
||||
if start >= s.len {
|
||||
return -1
|
||||
return none
|
||||
}
|
||||
mut i := strt
|
||||
for i < s.len {
|
||||
|
|
@ -1034,35 +1012,35 @@ pub fn (s string) index_after(p string, start int) int {
|
|||
}
|
||||
i++
|
||||
}
|
||||
return -1
|
||||
return none
|
||||
}
|
||||
|
||||
// index_byte returns the index of byte `c` if found in the string.
|
||||
// index_byte returns -1 if the byte can not be found.
|
||||
// index_byte returns `none` if the byte can not be found.
|
||||
[direct_array_access]
|
||||
pub fn (s string) index_byte(c byte) int {
|
||||
pub fn (s string) index_byte(c byte) ?int {
|
||||
for i in 0 .. s.len {
|
||||
if unsafe { s.str[i] } == c {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
return none
|
||||
}
|
||||
|
||||
// last_index_byte returns the index of the last occurence of byte `c` if found in the string.
|
||||
// last_index_byte returns -1 if the byte is not found.
|
||||
// last_index_byte returns `none` if the byte is not found.
|
||||
[direct_array_access]
|
||||
pub fn (s string) last_index_byte(c byte) int {
|
||||
pub fn (s string) last_index_byte(c byte) ?int {
|
||||
for i := s.len - 1; i >= 0; i-- {
|
||||
if unsafe { s.str[i] == c } {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
return none
|
||||
}
|
||||
|
||||
// count returns the number of occurrences of `substr` in the string.
|
||||
// count returns -1 if no `substr` could be found.
|
||||
// count returns 0 if no `substr` could be found.
|
||||
[direct_array_access]
|
||||
pub fn (s string) count(substr string) int {
|
||||
if s.len == 0 || substr.len == 0 {
|
||||
|
|
@ -1088,10 +1066,7 @@ pub fn (s string) count(substr string) int {
|
|||
|
||||
mut i := 0
|
||||
for {
|
||||
i = s.index_after(substr, i)
|
||||
if i == -1 {
|
||||
return n
|
||||
}
|
||||
i = s.index_after(substr, i) or { return n }
|
||||
i += substr.len
|
||||
n++
|
||||
}
|
||||
|
|
@ -1103,10 +1078,11 @@ pub fn (s string) contains(substr string) bool {
|
|||
if substr.len == 0 {
|
||||
return true
|
||||
}
|
||||
if s.index_(substr) == -1 {
|
||||
if _ := s.index(substr) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// contains_any returns `true` if the string contains any chars in `chars`.
|
||||
|
|
@ -1294,16 +1270,10 @@ pub fn (s string) is_title() bool {
|
|||
// find_between returns the string found between `start` string and `end` string.
|
||||
// Example: assert 'hey [man] how you doin'.find_between('[', ']') == 'man'
|
||||
pub fn (s string) find_between(start string, end string) string {
|
||||
start_pos := s.index_(start)
|
||||
if start_pos == -1 {
|
||||
return ''
|
||||
}
|
||||
start_pos := s.index(start) or { return '' }
|
||||
// First get everything to the right of 'start'
|
||||
val := s[start_pos + start.len..]
|
||||
end_pos := val.index_(end)
|
||||
if end_pos == -1 {
|
||||
return val
|
||||
}
|
||||
end_pos := val.index(end) or { return val }
|
||||
return val[..end_pos]
|
||||
}
|
||||
|
||||
|
|
@ -1582,11 +1552,11 @@ pub fn (s &string) free() {
|
|||
// Example: assert 'abcd'.before('.') == 'abcd'
|
||||
// TODO: deprecate and remove either .before or .all_before
|
||||
pub fn (s string) before(sub string) string {
|
||||
pos := s.index_(sub)
|
||||
if pos == -1 {
|
||||
if pos := s.index(sub) {
|
||||
return s[..pos]
|
||||
} else {
|
||||
return s.clone()
|
||||
}
|
||||
return s[..pos]
|
||||
}
|
||||
|
||||
// all_before returns the contents before `sub` in the string.
|
||||
|
|
@ -1595,11 +1565,11 @@ pub fn (s string) before(sub string) string {
|
|||
// Example: assert 'abcd'.all_before('.') == 'abcd'
|
||||
pub fn (s string) all_before(sub string) string {
|
||||
// TODO remove dup method
|
||||
pos := s.index_(sub)
|
||||
if pos == -1 {
|
||||
if pos := s.index(sub) {
|
||||
return s[..pos]
|
||||
} else {
|
||||
return s.clone()
|
||||
}
|
||||
return s[..pos]
|
||||
}
|
||||
|
||||
// all_before_last returns the contents before the last occurence of `sub` in the string.
|
||||
|
|
@ -1607,11 +1577,11 @@ pub fn (s string) all_before(sub string) string {
|
|||
// Example: assert '23:34:45.234'.all_before_last(':') == '23:34'
|
||||
// Example: assert 'abcd'.all_before_last('.') == 'abcd'
|
||||
pub fn (s string) all_before_last(sub string) string {
|
||||
pos := s.last_index_(sub)
|
||||
if pos == -1 {
|
||||
if pos := s.last_index(sub) {
|
||||
return s[..pos]
|
||||
} else {
|
||||
return s.clone()
|
||||
}
|
||||
return s[..pos]
|
||||
}
|
||||
|
||||
// all_after returns the contents after `sub` in the string.
|
||||
|
|
@ -1619,11 +1589,11 @@ pub fn (s string) all_before_last(sub string) string {
|
|||
// Example: assert '23:34:45.234'.all_after('.') == '234'
|
||||
// Example: assert 'abcd'.all_after('z') == 'abcd'
|
||||
pub fn (s string) all_after(sub string) string {
|
||||
pos := s.index_(sub)
|
||||
if pos == -1 {
|
||||
if pos := s.index(sub) {
|
||||
return s[pos + sub.len..]
|
||||
} else {
|
||||
return s.clone()
|
||||
}
|
||||
return s[pos + sub.len..]
|
||||
}
|
||||
|
||||
// all_after_last returns the contents after the last occurence of `sub` in the string.
|
||||
|
|
@ -1631,11 +1601,11 @@ pub fn (s string) all_after(sub string) string {
|
|||
// Example: assert '23:34:45.234'.all_after_last(':') == '45.234'
|
||||
// Example: assert 'abcd'.all_after_last('z') == 'abcd'
|
||||
pub fn (s string) all_after_last(sub string) string {
|
||||
pos := s.last_index_(sub)
|
||||
if pos == -1 {
|
||||
if pos := s.last_index(sub) {
|
||||
return s[pos + sub.len..]
|
||||
} else {
|
||||
return s.clone()
|
||||
}
|
||||
return s[pos + sub.len..]
|
||||
}
|
||||
|
||||
// after returns the contents after the last occurence of `sub` in the string.
|
||||
|
|
|
|||
|
|
@ -961,8 +961,12 @@ fn test_string_to_rune() {
|
|||
|
||||
fn test_index_any() {
|
||||
x := 'abcdefghij'
|
||||
assert x.index_any('ef') == 4
|
||||
assert x.index_any('fe') == 4
|
||||
if idx := x.index_any('ef') {
|
||||
assert idx == 4
|
||||
}
|
||||
if idx := x.index_any('fe') {
|
||||
assert idx == 4
|
||||
}
|
||||
}
|
||||
|
||||
fn test_string_f64() {
|
||||
|
|
|
|||
|
|
@ -94,8 +94,7 @@ pub fn decode_int_walpha(input string, alphabet Alphabet) ?int {
|
|||
mut total := 0 // to hold the results
|
||||
b58 := input.reverse()
|
||||
for i, ch in b58 {
|
||||
ch_i := alphabet.encode.bytestr().index_byte(ch)
|
||||
if ch_i == -1 {
|
||||
ch_i := alphabet.encode.bytestr().index_byte(ch) or {
|
||||
return error(@MOD + '.' + @FN +
|
||||
': input string contains values not found in the provided alphabet')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,11 +87,11 @@ fn (mut r Reader) read_line() ?string {
|
|||
return IError(&EndOfFileError{})
|
||||
}
|
||||
le := if r.is_mac_pre_osx_le { '\r' } else { '\n' }
|
||||
mut i := r.data.index_after(le, r.row_pos)
|
||||
mut i := r.data.index_after(le, r.row_pos) or { -1 }
|
||||
if i == -1 {
|
||||
if r.row_pos == 0 {
|
||||
// check for pre osx mac line endings
|
||||
i = r.data.index_after('\r', r.row_pos)
|
||||
i = r.data.index_after('\r', r.row_pos) or { -1 }
|
||||
if i != -1 {
|
||||
r.is_mac_pre_osx_le = true
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -37,10 +37,7 @@ pub fn (mut w Writer) write(record []string) ?bool {
|
|||
}
|
||||
w.sb.write_string('"')
|
||||
for field.len > 0 {
|
||||
mut i := field.index_any('"\r\n')
|
||||
if i < 0 {
|
||||
i = field.len
|
||||
}
|
||||
mut i := field.index_any('"\r\n') or { field.len }
|
||||
w.sb.write_string(field[..i])
|
||||
field = field[i..]
|
||||
if field.len > 0 {
|
||||
|
|
@ -69,7 +66,10 @@ fn (w &Writer) field_needs_quotes(field string) bool {
|
|||
if field == '' {
|
||||
return false
|
||||
}
|
||||
if field.contains(w.delimiter.ascii_str()) || (field.index_any('"\r\n') != -1) {
|
||||
if field.contains(w.delimiter.ascii_str()) {
|
||||
return true
|
||||
}
|
||||
if _ := field.index_any('"\r\n') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
|
|||
|
|
@ -305,7 +305,8 @@ fn (mut fs FlagParser) parse_bool_value(longhand string, shorthand byte) ?string
|
|||
fs.args.delete(i)
|
||||
return val
|
||||
}
|
||||
if arg.len > 1 && arg[0] == `-` && arg[1] != `-` && arg.index_byte(shorthand) != -1 {
|
||||
if arg.len > 1 && arg[0] == `-` && arg[1] != `-`
|
||||
&& arg.index_byte(shorthand) or { -1 } != -1 {
|
||||
// -abc is equivalent to -a -b -c
|
||||
return 'true'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ pub fn read_cookies(h map[string][]string, filter string) []&Cookie {
|
|||
mut line := line_.trim_space()
|
||||
mut part := ''
|
||||
for line.len > 0 {
|
||||
if line.index_any(';') > 0 {
|
||||
if _ := line.index_any(';') {
|
||||
line_parts := line.split(';')
|
||||
part = line_parts[0]
|
||||
line = line_parts[1]
|
||||
|
|
|
|||
|
|
@ -418,10 +418,7 @@ fn get_scheme(rawurl string) ?string {
|
|||
// sep. If cutc is true then sep is included with the second substring.
|
||||
// If sep does not occur in s then s and the empty string is returned.
|
||||
fn split(s string, sep byte, cutc bool) (string, string) {
|
||||
i := s.index_byte(sep)
|
||||
if i < 0 {
|
||||
return s, ''
|
||||
}
|
||||
i := s.index_byte(sep) or { return s, '' }
|
||||
if cutc {
|
||||
return s[..i], s[i + 1..]
|
||||
}
|
||||
|
|
@ -746,11 +743,10 @@ pub fn (u URL) str() string {
|
|||
// it would be mistaken for a scheme name. Such a segment must be
|
||||
// preceded by a dot-segment (e.g., './this:that') to make a relative-
|
||||
// path reference.
|
||||
i := path.index_byte(`:`)
|
||||
if i > -1 {
|
||||
if i := path.index_byte(`:`) {
|
||||
// TODO remove this when autofree handles tmp
|
||||
// expressions like this
|
||||
if i > -1 && path[..i].index_byte(`/`) == -1 {
|
||||
if i > -1 && path[..i].index_byte(`/`) or { -1 } == -1 {
|
||||
buf.write_string('./')
|
||||
}
|
||||
}
|
||||
|
|
@ -800,7 +796,7 @@ fn parse_query_values(mut m Values, query string) ?bool {
|
|||
mut q := query
|
||||
for q != '' {
|
||||
mut key := q
|
||||
mut i := key.index_any('&;')
|
||||
mut i := key.index_any('&;') or { -1 }
|
||||
if i >= 0 {
|
||||
q = key[i + 1..]
|
||||
key = key[..i]
|
||||
|
|
@ -1006,8 +1002,7 @@ pub fn (u &URL) port() string {
|
|||
fn split_host_port(hostport string) (string, string) {
|
||||
mut host := hostport
|
||||
mut port := ''
|
||||
colon := host.last_index_byte(`:`)
|
||||
if colon != -1 {
|
||||
if colon := host.last_index_byte(`:`) {
|
||||
if valid_optional_port(host[colon..]) {
|
||||
port = host[colon + 1..]
|
||||
host = host[..colon]
|
||||
|
|
|
|||
|
|
@ -109,8 +109,7 @@ pub fn environ() map[string]string {
|
|||
break
|
||||
}
|
||||
eline := unsafe { cstring_to_vstring(x) }
|
||||
eq_index := eline.index_byte(`=`)
|
||||
if eq_index > 0 {
|
||||
if eq_index := eline.index_byte(`=`) {
|
||||
res[eline[0..eq_index]] = eline[eq_index + 1..]
|
||||
}
|
||||
i++
|
||||
|
|
|
|||
|
|
@ -130,9 +130,7 @@ fn parse_comparator(input string) ?Comparator {
|
|||
fn parse_xrange(input string) ?Version {
|
||||
mut raw_ver := parse(input).complete()
|
||||
for typ in versions {
|
||||
if raw_ver.raw_ints[typ].index_any(semver.x_range_symbols) == -1 {
|
||||
continue
|
||||
}
|
||||
raw_ver.raw_ints[typ].index_any(semver.x_range_symbols) or { continue }
|
||||
match typ {
|
||||
ver_major {
|
||||
raw_ver.raw_ints[ver_major] = '0'
|
||||
|
|
@ -156,8 +154,9 @@ fn parse_xrange(input string) ?Version {
|
|||
}
|
||||
|
||||
fn can_expand(input string) bool {
|
||||
return input[0] == `~` || input[0] == `^` || input.contains(semver.hyphen_range_sep)
|
||||
|| input.index_any(semver.x_range_symbols) > -1
|
||||
return input[0] == `~` || input[0] == `^` || input.contains(semver.hyphen_range_sep) || input.index_any(semver.x_range_symbols) or {
|
||||
-1
|
||||
} > -1
|
||||
}
|
||||
|
||||
fn expand_comparator_set(input string) ?ComparatorSet {
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ pub fn (mut t Table) parse_cflag(cflg string, mod string, ctimedefines []string)
|
|||
if has_next {
|
||||
break
|
||||
}
|
||||
index = flag.index_after(' -', index + 1)
|
||||
index = flag.index_after(' -', index + 1) or { -1 }
|
||||
}
|
||||
if index == -1 {
|
||||
value = flag.trim_space()
|
||||
|
|
|
|||
|
|
@ -2975,7 +2975,7 @@ fn (mut p Parser) parse_number_literal() ast.Expr {
|
|||
lit := p.tok.lit
|
||||
full_lit := if is_neg { '-' + lit } else { lit }
|
||||
mut node := ast.empty_expr()
|
||||
if lit.index_any('.eE') >= 0 && lit[..2] !in ['0x', '0X', '0o', '0O', '0b', '0B'] {
|
||||
if lit.index_any('.eE') or { -1 } >= 0 && lit[..2] !in ['0x', '0X', '0o', '0O', '0b', '0B'] {
|
||||
node = ast.FloatLiteral{
|
||||
val: full_lit
|
||||
pos: pos
|
||||
|
|
|
|||
|
|
@ -1334,13 +1334,9 @@ fn trim_slash_line_break(s string) string {
|
|||
mut start := 0
|
||||
mut ret_str := s
|
||||
for {
|
||||
idx := ret_str.index_after('\\\n', start)
|
||||
if idx != -1 {
|
||||
ret_str = ret_str[..idx] + ret_str[idx + 2..].trim_left(' \n\t\v\f\r')
|
||||
start = idx
|
||||
} else {
|
||||
break
|
||||
}
|
||||
idx := ret_str.index_after('\\\n', start) or { break }
|
||||
ret_str = ret_str[..idx] + ret_str[idx + 2..].trim_left(' \n\t\v\f\r')
|
||||
start = idx
|
||||
}
|
||||
return ret_str
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue