feat: sort by type first, then sort by name/mtime/size (#241)
This commit is contained in:
parent
40df0bd2f9
commit
d9706d75ef
1 changed files with 42 additions and 8 deletions
|
@ -26,12 +26,13 @@ use hyper::header::{
|
||||||
use hyper::{Body, Method, StatusCode, Uri};
|
use hyper::{Body, Method, StatusCode, Uri};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs::Metadata;
|
use std::fs::Metadata;
|
||||||
use std::io::SeekFrom;
|
use std::io::SeekFrom;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{self, AtomicBool};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
use tokio::fs::File;
|
use tokio::fs::File;
|
||||||
|
@ -495,7 +496,7 @@ impl Server {
|
||||||
let mut it = WalkDir::new(&dir).into_iter();
|
let mut it = WalkDir::new(&dir).into_iter();
|
||||||
it.next();
|
it.next();
|
||||||
while let Some(Ok(entry)) = it.next() {
|
while let Some(Ok(entry)) = it.next() {
|
||||||
if !running.load(Ordering::SeqCst) {
|
if !running.load(atomic::Ordering::SeqCst) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let entry_path = entry.path();
|
let entry_path = entry.path();
|
||||||
|
@ -931,13 +932,28 @@ impl Server {
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if let Some(sort) = query_params.get("sort") {
|
if let Some(sort) = query_params.get("sort") {
|
||||||
if sort == "name" {
|
if sort == "name" {
|
||||||
paths.sort_by(|v1, v2| {
|
paths.sort_by(|v1, v2| match v1.path_type.cmp(&v2.path_type) {
|
||||||
alphanumeric_sort::compare_str(v1.name.to_lowercase(), v2.name.to_lowercase())
|
Ordering::Equal => {
|
||||||
|
alphanumeric_sort::compare_str(v1.name.clone(), v2.name.clone())
|
||||||
|
}
|
||||||
|
v => v,
|
||||||
})
|
})
|
||||||
} else if sort == "mtime" {
|
} else if sort == "mtime" {
|
||||||
paths.sort_by(|v1, v2| v1.mtime.cmp(&v2.mtime))
|
paths.sort_by(|v1, v2| match v1.path_type.cmp(&v2.path_type) {
|
||||||
|
Ordering::Equal => v1.mtime.cmp(&v2.mtime),
|
||||||
|
v => v,
|
||||||
|
})
|
||||||
} else if sort == "size" {
|
} else if sort == "size" {
|
||||||
paths.sort_by(|v1, v2| v1.size.unwrap_or(0).cmp(&v2.size.unwrap_or(0)))
|
paths.sort_by(|v1, v2| match v1.path_type.cmp(&v2.path_type) {
|
||||||
|
Ordering::Equal => {
|
||||||
|
if v1.is_dir() {
|
||||||
|
alphanumeric_sort::compare_str(v1.name.clone(), v2.name.clone())
|
||||||
|
} else {
|
||||||
|
v1.size.unwrap_or(0).cmp(&v2.size.unwrap_or(0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v => v,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if query_params
|
if query_params
|
||||||
.get("order")
|
.get("order")
|
||||||
|
@ -1254,7 +1270,7 @@ impl PathItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Debug, Serialize, Eq, PartialEq)]
|
||||||
enum PathType {
|
enum PathType {
|
||||||
Dir,
|
Dir,
|
||||||
SymlinkDir,
|
SymlinkDir,
|
||||||
|
@ -1262,6 +1278,24 @@ enum PathType {
|
||||||
SymlinkFile,
|
SymlinkFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Ord for PathType {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
let to_value = |t: &Self| -> u8 {
|
||||||
|
if matches!(t, Self::Dir | Self::SymlinkDir) {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
to_value(self).cmp(&to_value(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl PartialOrd for PathType {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn to_timestamp(time: &SystemTime) -> u64 {
|
fn to_timestamp(time: &SystemTime) -> u64 {
|
||||||
time.duration_since(SystemTime::UNIX_EPOCH)
|
time.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
|
@ -1336,7 +1370,7 @@ async fn zip_dir<W: AsyncWrite + Unpin>(
|
||||||
let mut it = WalkDir::new(&dir).into_iter();
|
let mut it = WalkDir::new(&dir).into_iter();
|
||||||
it.next();
|
it.next();
|
||||||
while let Some(Ok(entry)) = it.next() {
|
while let Some(Ok(entry)) = it.next() {
|
||||||
if !running.load(Ordering::SeqCst) {
|
if !running.load(atomic::Ordering::SeqCst) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let entry_path = entry.path();
|
let entry_path = entry.path();
|
||||||
|
|
Loading…
Reference in a new issue