use std::cmp::Ordering;
#[derive(Debug, Clone, Copy)]
pub enum SortMethod {
Name, Status, Activity, Platform, Id, }
impl SortMethod {
pub fn from_str(s: &str) -> Option<Self> {
match s.to_lowercase().as_str() {
"name" => Some(Self::Name),
"status" => Some(Self::Status),
"activity" => Some(Self::Activity),
"platform" => Some(Self::Platform),
"id" => Some(Self::Id),
_ => None,
}
}
pub fn all_methods() -> &'static [&'static str] {
&["name", "status", "activity", "platform", "id"]
}
}
pub fn sort_friends(
friends: &mut [vrchatapi::models::LimitedUserFriend],
method: SortMethod,
reverse: bool,
) {
friends.sort_by(|a, b| {
let ordering = match method {
SortMethod::Name => {
a.display_name
.to_lowercase()
.cmp(&b.display_name.to_lowercase())
}
SortMethod::Status => {
let a_priority = get_status_priority(&a.status);
let b_priority = get_status_priority(&b.status);
match a_priority.cmp(&b_priority) {
Ordering::Equal => a
.display_name
.to_lowercase()
.cmp(&b.display_name.to_lowercase()),
other => other,
}
}
SortMethod::Activity => {
match (&a.last_activity, &b.last_activity) {
(Some(a_activity), Some(b_activity)) => b_activity.cmp(a_activity),
(Some(_), None) => Ordering::Less,
(None, Some(_)) => Ordering::Greater,
(None, None) => a
.display_name
.to_lowercase()
.cmp(&b.display_name.to_lowercase()),
}
}
SortMethod::Platform => {
let a_platform = format_platform_for_sort(&a.last_platform);
let b_platform = format_platform_for_sort(&b.last_platform);
match a_platform.cmp(&b_platform) {
Ordering::Equal => a
.display_name
.to_lowercase()
.cmp(&b.display_name.to_lowercase()),
other => other,
}
}
SortMethod::Id => {
a.id.cmp(&b.id)
}
};
if reverse {
ordering.reverse()
} else {
ordering
}
});
}
fn get_status_priority(status: &vrchatapi::models::UserStatus) -> u8 {
match status {
vrchatapi::models::UserStatus::Active => 1, vrchatapi::models::UserStatus::JoinMe => 2, vrchatapi::models::UserStatus::AskMe => 3, vrchatapi::models::UserStatus::Busy => 4, vrchatapi::models::UserStatus::Offline => 5, }
}
fn format_platform_for_sort(platform: &str) -> String {
match platform.to_lowercase().as_str() {
p if p.contains("windows") || p.contains("standalonewindows") => "1_PC".to_string(),
p if p.contains("android") => "2_Quest".to_string(),
p if p.contains("ios") => "3_iOS".to_string(),
_ => format!("9_{platform}"), }
}