diff --git a/src/rust/amadeus-next/lkt-rs/src/args.rs b/src/rust/amadeus-next/lkt-rs/src/args.rs index 079c3403db6dc9ddd2499c19dda12a02ae61f858..485fe2a3613483713830637a8768f14bbff94a5b 100644 --- a/src/rust/amadeus-next/lkt-rs/src/args.rs +++ b/src/rust/amadeus-next/lkt-rs/src/args.rs @@ -17,6 +17,14 @@ struct Args { pub verbose: u8, } +/// Specify which to display karas from the queue. +#[derive(Debug, Clone)] +pub enum LktQueuePositions { + Range(Range<usize>), + NextItems(usize), + Default, +} + #[derive(Subcommand, Debug)] #[command(long_about = None, about = None)] enum SubCommand { @@ -40,14 +48,16 @@ enum SubCommand { status: bool, #[arg( action = clap::ArgAction::Set - , value_parser = crate::parsers::RangeParser::new() + , value_parser = crate::parsers::QueuePositionParser::new() , exclusive = true , short = 'l' , long = "list" - , help = "Prints the names and ids of karas in the queue. Karas are designated by a range of positions." - , id = "LOWER:UPPER" - )] - pos: Option<Option<Range<usize>>>, + , id = "LOWER:UPPER|COUNT" + , help = concat!( "Prints the names and ids of karas in the queue. Karas are designated by a range of positions, " + , "or the count to display from the playing kara. If no option is passed, the default number of " + , "karas is displayed from the currently played one." + ))] + pos: Option<Option<LktQueuePositions>>, #[arg( action = clap::ArgAction::SetTrue , exclusive = true @@ -331,6 +341,9 @@ pub(crate) enum LktQueueCommand { List { range: Range<usize>, }, + ListNext { + count: Option<usize>, + }, Next, Previous, @@ -433,8 +446,6 @@ impl LktCommand { SubCommand::Queue { shuffle: Some(lvl), .. } => Queue(LktQueueCommand::Shuffle { up_to_lvl: lvl.unwrap_or(LektorPriorityLevel::Enforce) }), SubCommand::Queue { clear: Some(lvl), .. } => Queue(LktQueueCommand::Clear { up_to_lvl: lvl.unwrap_or(LektorPriorityLevel::Enforce) }), SubCommand::Queue { seek: Some(id), .. } => { Queue(LktQueueCommand::SeekIdInQueue { id }) } - SubCommand::Queue { pos: Some(None), .. } => Queue(LktQueueCommand::List { range: 0..config.search.default_queue_count }), - SubCommand::Queue { pos: Some(Some(range)), .. } => Queue(LktQueueCommand::List { range }), SubCommand::Queue { play: Some(index), .. } => Queue(LktQueueCommand::Play { index }), SubCommand::Queue { swap: Some(args), .. } => match &args[..] { [p1, p2] => Queue(LktQueueCommand::SwapPositions { @@ -457,6 +468,10 @@ impl LktCommand { .map_err(|e| format!("invalid query in queue add command: {e}"))? }), } + SubCommand::Queue { pos: Some(Some(LktQueuePositions::Default)), .. } + | SubCommand::Queue { pos: Some(None), .. } => Queue(LktQueueCommand::ListNext { count: None }), + SubCommand::Queue { pos: Some(Some(LktQueuePositions::NextItems(count))), .. } => Queue(LktQueueCommand::ListNext { count: Some(count) }), + SubCommand::Queue { pos: Some(Some(LktQueuePositions::Range(range))), .. } => Queue(LktQueueCommand::List { range }), // SEARCH COMMANDS // diff --git a/src/rust/amadeus-next/lkt-rs/src/main.rs b/src/rust/amadeus-next/lkt-rs/src/main.rs index bc2ad06bc48fa34b8cc9b70bb7d0d765f5c561da..7f0ea07132f2971c6c684df3fa06be4972379dee 100644 --- a/src/rust/amadeus-next/lkt-rs/src/main.rs +++ b/src/rust/amadeus-next/lkt-rs/src/main.rs @@ -63,6 +63,8 @@ async fn handle_cmd_queue(_: LktConfig, mut conn: LektorConnexion, cmd: LktQueue }) } LktQueueCommand::List { range } => todo!(), + LktQueueCommand::ListNext { count } => todo!(), + LktQueueCommand::Next => send!(conn => LektorQuery::PlayNext; ok), LktQueueCommand::Previous => send!(conn => LektorQuery::PlayPrevious; ok), LktQueueCommand::Pause => { diff --git a/src/rust/amadeus-next/lkt-rs/src/parsers.rs b/src/rust/amadeus-next/lkt-rs/src/parsers.rs index 349b9224e2610de7ae53e5f8e91cf78bd88cd70e..f694ffd7a8778ff1a35bc2c851935ebc8715f303 100644 --- a/src/rust/amadeus-next/lkt-rs/src/parsers.rs +++ b/src/rust/amadeus-next/lkt-rs/src/parsers.rs @@ -5,16 +5,16 @@ use std::ops::Range; /// A parser for the [std::ops::Range] structure #[derive(Copy, Clone, Debug, Default)] #[non_exhaustive] -pub struct RangeParser {} +pub struct QueuePositionParser {} -impl RangeParser { +impl QueuePositionParser { pub fn new() -> Self { Default::default() } } -impl TypedValueParser for RangeParser { - type Value = Range<usize>; +impl TypedValueParser for QueuePositionParser { + type Value = crate::args::LktQueuePositions; fn parse_ref( &self, @@ -22,6 +22,7 @@ impl TypedValueParser for RangeParser { arg: Option<&clap::Arg>, value: &std::ffi::OsStr, ) -> Result<Self::Value, clap::Error> { + use crate::args::LktQueuePositions as QPV; let name = cmd.get_name(); let arg = arg .map(ToString::to_string) @@ -32,29 +33,38 @@ impl TypedValueParser for RangeParser { format!("not a valid utf8 string: {}", value.to_string_lossy()), ) })?; - match value.split(':').collect::<Vec<_>>()[..] { - [lower, upper] => { - let lower = lower.parse::<usize>().map_err(|e| { - clap::Error::raw( - ErrorKind::InvalidValue, - format!("in `{name} {arg}`, the value is not an integer: {e}"), - ) - })?; - let upper = upper.parse::<usize>().map_err(|e| { - clap::Error::raw( - ErrorKind::InvalidValue, - format!("in `{name} {arg}`, the value is not an integer: {e}"), - ) - })?; - either!(lower <= upper => Ok(lower..upper); Err(clap::Error::raw( + let value = value.trim(); + + if value.is_empty() { + // Default value + Ok(QPV::Default) + } else if let Ok(value) = value.parse::<usize>() { + // A count from the playing kara + Ok(QPV::NextItems(value)) + } else if let [lower, upper] = value.split(':').collect::<Vec<_>>()[..] { + // The range + let lower = lower.parse::<usize>().map_err(|e| { + clap::Error::raw( + ErrorKind::InvalidValue, + format!("in `{name} {arg}`, the value is not an integer: {e}"), + ) + })?; + let upper = upper.parse::<usize>().map_err(|e| { + clap::Error::raw( ErrorKind::InvalidValue, - format!("in `{name} {arg}`, the range must be valid, unlike `{lower}:{upper}`, did you meant to write `{upper}:{lower}` instead?"), - ))) - } - _ => Err(clap::Error::raw( + format!("in `{name} {arg}`, the value is not an integer: {e}"), + ) + })?; + either!(lower <= upper => Ok(QPV::Range(lower..upper)); Err(clap::Error::raw( + ErrorKind::InvalidValue, + format!("in `{name} {arg}`, the range must be valid, unlike `{lower}:{upper}`, did you meant to write `{upper}:{lower}` instead?"), + ))) + } else { + // Error + Err(clap::Error::raw( ErrorKind::InvalidValue, - format!("in `{name} {arg}`, the value should be of the form: `[lower]:[upper]`"), - )), + format!("in `{name} {arg}`, the value should be of the form: `[lower]:[upper]` or `[count]` or empty"), + )) } } }