///|
fn linkify_host_view(value : StringView) -> StringView? {
let mut pos = 0
for ch in value {
match ch {
'/' | '?' | '#' => return value.get_view(start=0, end=pos)
_ => pos += ch.utf16_len()
}
}
value.get_view(start=0, end=value.length())
}
///|
fn linkify_host_without_userinfo_port(hostport : StringView) -> StringView {
let host = linkify_strip_userinfo(hostport)
linkify_split_host_port(host).0
}
///|
fn linkify_strip_userinfo(hostport : StringView) -> StringView {
match linkify_last_char_index(hostport, '@') {
Some(at) => hostport[at + 1:hostport.length()]
None => hostport
}
}
///|
fn linkify_split_host_port(hostport : StringView) -> (StringView, String) {
if hostport.has_prefix("[") {
return (hostport, "")
}
match linkify_last_char_index(hostport, ':') {
Some(colon) =>
(hostport[0:colon], hostport[colon + 1:hostport.length()].to_owned())
None => (hostport, "")
}
}
///|
fn linkify_after_url_scheme(candidate : StringView) -> StringView? {
let start = if @syn.starts_with_case_insensitive(candidate, 0, "http://") {
7
} else if @syn.starts_with_case_insensitive(candidate, 0, "https://") {
8
} else if @syn.starts_with_case_insensitive(candidate, 0, "ftp://") {
6
} else {
return None
}
candidate.get_view(start~, end=candidate.length())
}
///|
fn linkify_valid_ipv4(host : StringView) -> Bool {
let mut parts = 0
let mut pos = 0
let mut part_start = 0
for ch in host {
if ch == '.' {
if !linkify_valid_ipv4_part(host[part_start:pos]) {
return false
}
parts += 1
part_start = pos + 1
}
pos += ch.utf16_len()
}
if !linkify_valid_ipv4_part(host[part_start:host.length()]) {
return false
}
parts += 1
parts == 4
}
///|
fn linkify_valid_ipv4_part(part : StringView) -> Bool {
guard linkify_parse_uint(part) is Some(value) else { return false }
!part.is_empty() && part.length() <= 3 && value <= 255
}