Extract PositionArgs for shared --before/--after flags
Deduplicates the positioning flags and key-to-id resolution between
task create and task move using clap flatten.

Assisted-by: Claude Opus 4.6 via pi
change umztursklsqzlmyvvpxmzvyvwwpooump
commit a6c29afa2f67514f59cf0eb1285871bfd6cfe924
author Alpha Chen <alpha@kejadlen.dev>
date
parent tlqtpqns
diff --git a/src/bin/ranger/commands/task.rs b/src/bin/ranger/commands/task.rs
index 4ee5aee..d87c8f2 100644
--- a/src/bin/ranger/commands/task.rs
+++ b/src/bin/ranger/commands/task.rs
@@ -1,4 +1,4 @@
-use clap::Subcommand;
+use clap::{Args, Subcommand};
 use color_eyre::eyre::Result;
 use ranger::db::SqlitePool;
 use ranger::models::{State, Task};
@@ -6,6 +6,33 @@ use ranger::ops;
 
 use crate::output;
 
+/// Positioning flags shared by create and move.
+#[derive(Args)]
+pub struct PositionArgs {
+    /// Place before this task key
+    #[arg(long)]
+    before: Option<String>,
+    /// Place after this task key
+    #[arg(long)]
+    after: Option<String>,
+}
+
+impl PositionArgs {
+    async fn resolve(self, pool: &SqlitePool) -> Result<(Option<i64>, Option<i64>)> {
+        let before_id = if let Some(k) = &self.before {
+            Some(ops::task::get_by_key_prefix(pool, k).await?.id)
+        } else {
+            None
+        };
+        let after_id = if let Some(k) = &self.after {
+            Some(ops::task::get_by_key_prefix(pool, k).await?.id)
+        } else {
+            None
+        };
+        Ok((before_id, after_id))
+    }
+}
+
 #[derive(Subcommand)]
 pub enum TaskCommands {
     /// Create a new task
@@ -27,12 +54,8 @@ pub enum TaskCommands {
         /// Tags to add (comma-separated)
         #[arg(long)]
         tag: Option<String>,
-        /// Place before this task key
-        #[arg(long)]
-        before: Option<String>,
-        /// Place after this task key
-        #[arg(long)]
-        after: Option<String>,
+        #[command(flatten)]
+        position: PositionArgs,
     },
     /// List tasks
     List {
@@ -66,15 +89,11 @@ pub enum TaskCommands {
     Move {
         /// Task key or prefix
         key: String,
-        /// Place before this task key
-        #[arg(long)]
-        before: Option<String>,
-        /// Place after this task key
-        #[arg(long)]
-        after: Option<String>,
         /// Backlog to reorder within
         #[arg(long)]
         backlog: String,
+        #[command(flatten)]
+        position: PositionArgs,
     },
     /// Add a task to a backlog
     Add {
@@ -106,8 +125,7 @@ pub async fn run(pool: &SqlitePool, command: TaskCommands, json: bool) -> Result
             state,
             parent,
             tag,
-            before,
-            after,
+            position,
         } => {
             let bl = ops::backlog::get_by_key_prefix(pool, &backlog).await?;
             let parent_id = if let Some(parent_key) = &parent {
@@ -115,18 +133,7 @@ pub async fn run(pool: &SqlitePool, command: TaskCommands, json: bool) -> Result
             } else {
                 None
             };
-
-            let before_id = if let Some(k) = &before {
-                Some(ops::task::get_by_key_prefix(pool, k).await?.id)
-            } else {
-                None
-            };
-            let after_id = if let Some(k) = &after {
-                Some(ops::task::get_by_key_prefix(pool, k).await?.id)
-            } else {
-                None
-            };
-
+            let (before_id, after_id) = position.resolve(pool).await?;
             let state = state.map(|s| s.parse::<State>()).transpose()?;
 
             let task = ops::task::create(
@@ -232,23 +239,12 @@ pub async fn run(pool: &SqlitePool, command: TaskCommands, json: bool) -> Result
         }
         TaskCommands::Move {
             key,
-            before,
-            after,
             backlog,
+            position,
         } => {
             let bl = ops::backlog::get_by_key_prefix(pool, &backlog).await?;
             let task = ops::task::get_by_key_prefix(pool, &key).await?;
-
-            let before_id = if let Some(k) = &before {
-                Some(ops::task::get_by_key_prefix(pool, k).await?.id)
-            } else {
-                None
-            };
-            let after_id = if let Some(k) = &after {
-                Some(ops::task::get_by_key_prefix(pool, k).await?.id)
-            } else {
-                None
-            };
+            let (before_id, after_id) = position.resolve(pool).await?;
 
             ops::task::move_task(pool, task.id, bl.id, before_id, after_id).await?;
             println!("Moved {} {}", &task.key[..8], task.title);