diff options
author | elandsborough <elliott.landsborough@gmail.com> | 2024-01-10 19:53:36 +0000 |
---|---|---|
committer | ElliottLandsborough <elliott.landsborough@gmail.com> | 2024-01-13 03:28:24 +0000 |
commit | e5e3ad2fed80bea3f2c9c90f87a405bca077691e (patch) | |
tree | 80c37e10ad52880d35efb55fbead0f17afa83323 | |
parent | Skip newline test case on Windows (diff) | |
download | miniserve-e5e3ad2fed80bea3f2c9c90f87a405bca077691e.tar.gz miniserve-e5e3ad2fed80bea3f2c9c90f87a405bca077691e.zip |
Set default sorting order and method with arguments
-rw-r--r-- | README.md | 12 | ||||
-rw-r--r-- | src/args.rs | 20 | ||||
-rw-r--r-- | src/config.rs | 27 | ||||
-rw-r--r-- | src/listing.rs | 12 | ||||
-rw-r--r-- | src/renderer.rs | 4 | ||||
-rw-r--r-- | tests/navigation.rs | 30 | ||||
-rw-r--r-- | tests/utils/mod.rs | 16 |
7 files changed, 116 insertions, 5 deletions
@@ -210,6 +210,18 @@ Options: [env: MINISERVE_HIDDEN=] + -S, --default-sorting-method + Default sort method for file list + + [env: MINISERVE_DEFAULT_SORTING_METHOD=] + [possible values: name, date, size] + + -O, --default-sorting-order + Default sort order for file list + + [env: MINISERVE_DEFAULT_SORTING_ORDER=] + [possible values: asc, desc] + -c, --color-scheme <COLOR_SCHEME> Default color scheme diff --git a/src/args.rs b/src/args.rs index c5c268f..e400c8a 100644 --- a/src/args.rs +++ b/src/args.rs @@ -113,6 +113,26 @@ pub struct CliArgs { #[arg(short = 'H', long = "hidden", env = "MINISERVE_HIDDEN")] pub hidden: bool, + /// Default sorting method for file list + #[arg( + short = 'S', + long = "default-sorting-method", + default_value = "", + ignore_case = true, + env = "MINISERVE_DEFAULT_SORTING_METHOD" + )] + pub default_sorting_method: String, + + /// Default sorting order for file list + #[arg( + short = 'O', + long = "default-sorting-order", + default_value = "", + ignore_case = true, + env = "MINISERVE_DEFAULT_SORTING_ORDER" + )] + pub default_sorting_order: String, + /// Default color scheme #[arg( short = 'c', diff --git a/src/config.rs b/src/config.rs index 1ef9eca..491ac40 100644 --- a/src/config.rs +++ b/src/config.rs @@ -15,6 +15,7 @@ use crate::{ args::{parse_auth, CliArgs, MediaType}, auth::RequiredAuth, file_utils::sanitize_path, + listing::{SortingMethod, SortingOrder}, renderer::ThemeSlug, }; @@ -50,6 +51,12 @@ pub struct MiniserveConfig { /// Show hidden files pub show_hidden: bool, + /// Default sorting method + pub default_sorting_method: Option<SortingMethod>, + + /// Default sorting order + pub default_sorting_order: Option<SortingOrder>, + /// Route prefix; Either empty or prefixed with slash pub route_prefix: String, @@ -265,6 +272,24 @@ impl MiniserveConfig { .transpose()? .unwrap_or_default(); + let default_sorting_method: Option<SortingMethod> = match args + .default_sorting_method + .to_owned() + .parse::<SortingMethod>() + { + Ok(value) => Some(value), + Err(_) => None, + }; + + let default_sorting_order: Option<SortingOrder> = match args + .default_sorting_order + .to_owned() + .parse::<SortingOrder>() + { + Ok(value) => Some(value), + Err(_) => None, + }; + Ok(MiniserveConfig { verbose: args.verbose, path: args.path.unwrap_or_else(|| PathBuf::from(".")), @@ -274,6 +299,8 @@ impl MiniserveConfig { path_explicitly_chosen, no_symlinks: args.no_symlinks, show_hidden: args.hidden, + default_sorting_method, + default_sorting_order, route_prefix, favicon_route, css_route, diff --git a/src/listing.rs b/src/listing.rs index 6e75b0e..40c5a77 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -223,7 +223,7 @@ pub fn directory_listing( res }; - let query_params = extract_query_parameters(req); + let mut query_params = extract_query_parameters(req); let mut entries: Vec<Entry> = Vec::new(); let mut readme: Option<(String, String)> = None; @@ -299,6 +299,14 @@ pub fn directory_listing( } } + if query_params.sort.is_none() { + query_params.sort = conf.default_sorting_method + } + + if query_params.order.is_none() { + query_params.order = conf.default_sorting_order + } + match query_params.sort.unwrap_or(SortingMethod::Name) { SortingMethod::Name => entries.sort_by(|e1, e2| { alphanumeric_sort::compare_str(e1.name.to_lowercase(), e2.name.to_lowercase()) @@ -319,7 +327,7 @@ pub fn directory_listing( }), }; - if let Some(SortingOrder::Descending) = query_params.order { + if let Some(SortingOrder::Ascending) = query_params.order { entries.reverse() } diff --git a/src/renderer.rs b/src/renderer.rs index 5a591f0..3b62704 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -459,7 +459,7 @@ fn build_link( ) -> Markup { let mut link = format!("?sort={name}&order=asc"); let mut help = format!("Sort by {name} in ascending order"); - let mut chevron = chevron_up(); + let mut chevron = chevron_down(); let mut class = ""; if let Some(method) = sort_method { @@ -469,7 +469,7 @@ fn build_link( if order.to_string() == "asc" { link = format!("?sort={name}&order=desc"); help = format!("Sort by {name} in descending order"); - chevron = chevron_down(); + chevron = chevron_up(); } } } diff --git a/tests/navigation.rs b/tests/navigation.rs index 3bd7415..34eee2f 100644 --- a/tests/navigation.rs +++ b/tests/navigation.rs @@ -1,12 +1,13 @@ mod fixtures; mod utils; -use fixtures::{server, Error, TestServer, DEEPLY_NESTED_FILE, DIRECTORIES}; +use fixtures::{server, Error, TestServer, FILES, DEEPLY_NESTED_FILE, DIRECTORIES}; use pretty_assertions::{assert_eq, assert_ne}; use rstest::rstest; use select::document::Document; use std::process::{Command, Stdio}; use utils::get_link_from_text; +use utils::get_link_hrefs_from_text_with_prefix; #[rstest( input, @@ -147,3 +148,30 @@ fn can_navigate_using_breadcrumbs( Ok(()) } + +#[rstest] +#[case(server(&["--default-sorting-method", "date", "--default-sorting-order", "desc"]))] +#[case(server(&["--default-sorting-method", "date", "--default-sorting-order", "asc"]))] +/// We can specify the default sorting order +fn can_specify_default_sorting_order(#[case] server: TestServer) -> Result<(), Error> { + let slash = String::from("/"); + let base_url = server.url(); + let nested_url = base_url.join(&slash)?; + + let resp = reqwest::blocking::get(nested_url.as_str())?; + let body = resp.error_for_status()?; + let parsed = Document::from_read(body)?; + + let links = get_link_hrefs_from_text_with_prefix(&parsed, "/"); + let first_created_file = slash + FILES.first().unwrap(); + + if links.first().unwrap() == &first_created_file { + assert_eq!("/very/?sort=date&order=asc", links.last().unwrap()); + } + + if links.last().unwrap() == &first_created_file { + assert_eq!("/very/?sort=date&order=desc", links.first().unwrap()); + } + + Ok(()) +} diff --git a/tests/utils/mod.rs b/tests/utils/mod.rs index 734d33b..64433fc 100644 --- a/tests/utils/mod.rs +++ b/tests/utils/mod.rs @@ -12,3 +12,19 @@ pub fn get_link_from_text(document: &Document, text: &str) -> Option<String> { .next()?; Some(a_elem.attr("href")?.to_string()) } + +/// Return the href attributes of all links that start with the specified prefix `text`. +pub fn get_link_hrefs_from_text_with_prefix(document: &Document, text: &str) -> Vec<String> { + let mut vec: Vec<String> = Vec::new(); + + let a_elem = document.find(Name("a")); + + for element in a_elem { + let str = element.attr("href").unwrap_or(""); + if str.to_string().starts_with(text) { + vec.push(str.to_string()); + } + } + + return vec; +} |