pub struct ImportPath;
impl ImportPath {
pub fn decides_order(previous: &str, item: &str) -> bool {
Self::is_specially_ordered(previous)
|| Self::is_specially_ordered(item)
|| Self::diverges_by_case(previous, item)
|| Self::one_extends_the_other(previous, item)
}
pub fn is_specially_ordered(import: &str) -> bool {
let first = Self::first_segment(import);
matches!(first, "self" | "super" | "crate")
|| first.chars().next().is_some_and(char::is_uppercase)
}
fn diverges_by_case(previous: &str, item: &str) -> bool {
Self::segments(previous)
.into_iter()
.zip(Self::segments(item))
.find(|(left, right)| left != right)
.is_some_and(|(left, right)| !Self::share_a_case_shape(left, right))
}
fn share_a_case_shape(left: &str, right: &str) -> bool {
Self::is_uppercase(left) == Self::is_uppercase(right)
&& Self::is_all_capitals(left) == Self::is_all_capitals(right)
}
fn is_all_capitals(segment: &str) -> bool {
segment.chars().any(char::is_uppercase) && !segment.chars().any(char::is_lowercase)
}
fn one_extends_the_other(previous: &str, item: &str) -> bool {
let (left, right) = (Self::segments(previous), Self::segments(item));
let shared = left.len().min(right.len());
left.len() != right.len() && left[..shared] == right[..shared]
}
fn first_segment(import: &str) -> &str {
Self::segments(import).first().copied().unwrap_or_default()
}
fn is_uppercase(segment: &str) -> bool {
segment.chars().next().is_some_and(char::is_uppercase)
}
fn segments(import: &str) -> Vec<&str> {
import
.trim()
.trim_start_matches("pub ")
.trim_start_matches("use ")
.trim_start()
.trim_end_matches(';')
.trim_start_matches("::")
.split("::")
.map(str::trim)
.collect()
}
}