Răsfoiți Sursa

Add some documentation and flesh out Cargo.toml.

Kestrel 19 ore în urmă
părinte
comite
19dcfe7ef2
3 a modificat fișierele cu 56 adăugiri și 6 ștergeri
  1. 7 4
      Cargo.toml
  2. 5 1
      derive/Cargo.toml
  3. 44 1
      src/lib.rs

+ 7 - 4
Cargo.toml

@@ -1,13 +1,16 @@
 [package]
+authors = ["kestrel <kestrel@flying-kestrel.ca>"]
+categories = ["command-line-interface"]
+description = "cliask is a crate to handle prompting the user for input in a CLI context"
+edition = "2024"
+keywords = ["cli", "input", "prompt", "ask", "interactive"]
+license = "LGPL-3.0-only"
 name = "cliask"
+repository = "https://git.flying-kestrel.ca/kestrel/cliask"
 version = "0.1.0"
-edition = "2024"
 
 [dependencies]
 cliask-derive = { path = "derive", version = "0.1.0" }
 
 termion = { version = "4" }
 unicode-segmentation = { version = "1" }
-
-# console = { version = "0.16", default-features = false, features = [ "std", "unicode-width" ] }
-# crossterm = { version = "0.29.0", default-features = false, features = [ "events", "filedescriptor" ] }

+ 5 - 1
derive/Cargo.toml

@@ -1,7 +1,11 @@
 [package]
+authors = ["kestrel <kestrel@flying-kestrel.ca>"]
+description = "proc-macro crate for cliask"
+edition = "2024"
+license = "LGPL-3.0-only"
 name = "cliask-derive"
+repository = "https://git.flying-kestrel.ca/kestrel/cliask"
 version = "0.1.0"
-edition = "2024"
 
 [lib]
 proc-macro = true

+ 44 - 1
src/lib.rs

@@ -1,12 +1,32 @@
+//! cliask is a crate to handle prompting the user for input in CLI applications that don't want
+//! a full TUI library such as [cursive](https://lib.rs/crates/cursive/) and want something simpler
+//! than [inquire](https://lib.rs/crates/inquire).
+
 use std::io::Write;
 use std::os::fd::AsFd;
 use termion::{raw::IntoRawMode, input::TermRead};
 
+extern crate self as cliask;
+
+/// Derives [`ActionEnum`] for a given enum, automatically assigning keys based on uppercase
+/// characters in the enum variant names.
+///
+/// For example:
+/// ```
+/// #[derive(ActionEnum)]
+/// pub enum YesNoSkipAction {
+///     Yes,     // key will be Y
+///     No,      // key will be N
+///     Skip,    // key will be S
+///     SkipAll, // key will be A, since S is used already
+/// }
+/// // prompt will be the choice (Y)es/(N)o/(S)kip/Skip(A)ll
+/// ```
 pub use cliask_derive::ActionEnum;
 
+/// Represents errors encountered during prompting.
 #[derive(Debug)]
 pub enum AskError {
-    EscapeRequest,
     IOError(std::io::Error),
 }
 
@@ -16,6 +36,7 @@ impl From<std::io::Error> for AskError {
     }
 }
 
+/// Trait providing static information about action choices.
 pub trait ActionEnum: 'static {
     const LABELS: &'static [&'static str];
     const KEYS: &'static [char];
@@ -25,6 +46,23 @@ pub trait ActionEnum: 'static {
     fn action_index(&self) -> usize;
 }
 
+/// A simple [`ActionEnum`] for asking yes/no questions.
+#[derive(ActionEnum)]
+pub enum YesNoAction {
+    Yes,
+    No,
+}
+
+impl From<YesNoAction> for bool {
+    fn from(value: YesNoAction) -> Self {
+        match value {
+            YesNoAction::Yes => true,
+            YesNoAction::No => false,
+        }
+    }
+}
+
+/// Prompt the user for an action from a static list.
 pub struct ActionPrompt<AE: ActionEnum> {
     default_action: Option<AE>,
 }
@@ -117,16 +155,19 @@ impl<AE: ActionEnum> ActionPrompt<AE> {
         
     }
 
+    /// Run the prompt.
     pub fn run(self) -> Result<AE, AskError> {
         self.print_prompt()?;
         self.wait_for_answer(false).map(Option::unwrap)
     }
+    /// Run the prompt and allow cancellation via the escape key.
     pub fn run_cancellable(self) -> Result<Option<AE>, AskError> {
         self.print_prompt()?;
         self.wait_for_answer(true)
     }
 }
 
+/// Prompt the user for a selection from a dynamic list.
 pub struct SelectPrompt<'l, T: std::fmt::Display> {
     prompt: &'l str,
     height: usize,
@@ -320,6 +361,7 @@ impl<'l, T: std::fmt::Display> SelectPrompt<'l, T> {
         Ok(None)
     }
 
+    /// Run the prompt.
     pub fn run(mut self) -> Result<T, AskError> {
         let mut stdout = std::io::stdout();
         self.setup(&mut stdout)?;
@@ -329,6 +371,7 @@ impl<'l, T: std::fmt::Display> SelectPrompt<'l, T> {
         r
     }
 
+    /// Run the prompt and allow cancellation via the escape key.
     pub fn run_cancellable(mut self) -> Result<Option<T>, AskError> {
         let mut stdout = std::io::stdout();
         self.setup(&mut stdout)?;