Skip to content

Commit 67e60b2

Browse files
committed
Fallback for ilog10 for older versions of Rust
1 parent dda33b7 commit 67e60b2

File tree

1 file changed

+38
-2
lines changed

1 file changed

+38
-2
lines changed

url/src/slicing.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,43 @@ 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+
if cfg!(int_log) {
44+
return n.checked_ilog10().unwrap_or(0) as usize + 1;
45+
}
46+
// fall-back before 1.67
47+
// we avoid a branch to handle the special case of n == 0 by starting at m = 10 instead of m = 1
48+
let mut m = 10;
49+
let mut log10m = 1;
50+
while m <= n {
51+
log10m += 1;
52+
if let Some(m_times_10) = m.checked_mul(10) {
53+
m = m_times_10;
54+
} else {
55+
// m * 10 would overflow, so it must be bigger than n
56+
// we break our invariant log10(m) == log10m
57+
// it's okay because we won't use m anymore
58+
break;
59+
}
60+
}
61+
// we now have 10**(log10m - 1) <= n < 10**log10m
62+
log10m
63+
}
64+
65+
#[test]
66+
fn test_count_digits() {
67+
assert_eq!(count_digits(0), 1);
68+
assert_eq!(count_digits(1), 1);
69+
assert_eq!(count_digits(9), 1);
70+
assert_eq!(count_digits(10), 2);
71+
assert_eq!(count_digits(99), 2);
72+
assert_eq!(count_digits(100), 3);
73+
assert_eq!(count_digits(9999), 4);
74+
assert_eq!(count_digits(65535), 5);
75+
}
76+
4077
/// Indicates a position within a URL based on its components.
4178
///
4279
/// A range of positions can be used for slicing `Url`:
@@ -152,8 +189,7 @@ impl Url {
152189
Position::AfterPort => {
153190
if let Some(port) = self.port {
154191
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
192+
self.host_end as usize + ":".len() + count_digits(port)
157193
} else {
158194
self.host_end as usize
159195
}

0 commit comments

Comments
 (0)