Skip to content

Commit 09090fd

Browse files
committed
Fallback for ilog10 for older versions of Rust
1 parent dda33b7 commit 09090fd

File tree

1 file changed

+37
-2
lines changed

1 file changed

+37
-2
lines changed

url/src/slicing.rs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,42 @@ impl Index<Range<Position>> for Url {
3737
}
3838
}
3939

40+
// Counts how many base-10 digits are required to represent n in the given base
41+
fn count_digits(n: u16) -> usize {
42+
// just use ilog10 in 1.67+
43+
#[cfg(int_log)]
44+
return n.checked_ilog10().unwrap_or(0) as usize + 1;
45+
// fall-back before 1.67
46+
// we avoid a branch to handle the special case of n == 0 by starting at m = 10 instead of m = 1
47+
let mut m = 10;
48+
let mut log10m = 1;
49+
while m <= n {
50+
log10m += 1;
51+
if let Some(m_times_10) = m.checked_mul(10) {
52+
m = m_times_10;
53+
} else {
54+
// m * 10 would overflow, so it must be bigger than n
55+
// we break our invariant log10(m) == log10m
56+
// it's okay because we won't use m anymore
57+
break;
58+
}
59+
}
60+
// we now have 10**(log10m - 1) <= n < 10**log10m
61+
log10m
62+
}
63+
64+
#[test]
65+
fn test_count_digits() {
66+
assert_eq!(count_digits(0), 1);
67+
assert_eq!(count_digits(1), 1);
68+
assert_eq!(count_digits(9), 1);
69+
assert_eq!(count_digits(10), 2);
70+
assert_eq!(count_digits(99), 2);
71+
assert_eq!(count_digits(100), 3);
72+
assert_eq!(count_digits(9999), 4);
73+
assert_eq!(count_digits(65535), 5);
74+
}
75+
4076
/// Indicates a position within a URL based on its components.
4177
///
4278
/// A range of positions can be used for slicing `Url`:
@@ -152,8 +188,7 @@ impl Url {
152188
Position::AfterPort => {
153189
if let Some(port) = self.port {
154190
debug_assert!(self.byte_at(self.host_end) == b':');
155-
let port_length = port.checked_ilog10().unwrap_or(0) as usize + 1;
156-
self.host_end as usize + ":".len() + port_length
191+
self.host_end as usize + ":".len() + count_digits(port)
157192
} else {
158193
self.host_end as usize
159194
}

0 commit comments

Comments
 (0)