aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA Farzat <a@farzat.xyz>2026-02-07 18:48:37 +0300
committerA Farzat <a@farzat.xyz>2026-02-07 18:48:37 +0300
commit9d3bff94d9dfc332a6bb05efc923135cf22a35d2 (patch)
tree7e8deecd32822d4d8313f37f05dce7d992a0cbc6
parent1ab3e634169435d28077fe32ad36b5ddbde50750 (diff)
downloadsafaribooks-rs-9d3bff94d9dfc332a6bb05efc923135cf22a35d2.tar.gz
safaribooks-rs-9d3bff94d9dfc332a6bb05efc923135cf22a35d2.zip
Add CLI parsing
-rw-r--r--Cargo.toml1
-rw-r--r--src/cli.rs66
-rw-r--r--src/main.rs8
3 files changed, 75 insertions, 0 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 7ac047e..6c3a0b2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,3 +4,4 @@ version = "0.1.0"
edition = "2024"
[dependencies]
+clap = { version = "4.5", features = ["derive"] }
diff --git a/src/cli.rs b/src/cli.rs
new file mode 100644
index 0000000..a223b8c
--- /dev/null
+++ b/src/cli.rs
@@ -0,0 +1,66 @@
+use clap::Parser;
+
+/// Minimal SafariBooks port (cookies only).
+#[derive(Parser, Debug, PartialEq)]
+#[command(version)]
+pub struct Args {
+ /// Book digits ID from the O'Reilly URL.
+ pub bookid: String,
+
+ /// Do not delete the log file on success.
+ #[arg(long = "preserve-log")]
+ pub preserve_log: bool,
+}
+
+#[cfg(test)]
+mod tests {
+ use super::Args;
+ use clap::{CommandFactory, Parser};
+
+ #[test]
+ fn parses_positional_bookid_only() {
+ // safaribooks-rs 9781491958698
+ let args = Args::try_parse_from(["safaribooks-rs", "9781491958698"]).unwrap();
+ assert_eq!(args.bookid, "9781491958698");
+ assert!(!args.preserve_log);
+ }
+
+ #[test]
+ fn parses_with_preserve_log_flag() {
+ // safaribooks-rs --preserve-log 9781491958698
+ let args =
+ Args::try_parse_from(["safaribooks-rs", "--preserve-log", "9781491958698"]).unwrap();
+ assert_eq!(args.bookid, "9781491958698");
+ assert!(args.preserve_log);
+ }
+
+ #[test]
+ fn error_when_missing_bookid() {
+ // safaribooks-rs --preserve-log
+ let err = Args::try_parse_from(["safaribooks-rs", "--preserve-log"]).unwrap_err();
+ let msg = err.to_string();
+ // clap’s message should indicate the missing required argument
+ assert!(msg.contains("<BOOKID>"));
+ }
+
+ #[test]
+ fn error_on_unknown_flag() {
+ // safaribooks-rs --kindle 9781491958698
+ let err =
+ Args::try_parse_from(["safaribooks-rs", "--kindle", "9781491958698"]).unwrap_err();
+ let msg = err.to_string().to_lowercase();
+ assert!(msg.contains("unexpected argument '--kindle' found"));
+ }
+
+ #[test]
+ fn help_and_version_are_available() {
+ // `--help` and `--version` are auto-provided by clap
+ let help = Args::command().render_help().to_string();
+ assert!(help.contains("Usage:"));
+ assert!(help.contains("<BOOKID>"));
+ assert!(help.contains("--preserve-log"));
+
+ let version = Args::command().render_version();
+ assert!(!version.trim().is_empty());
+ }
+}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..3b3e84d
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,8 @@
+mod cli;
+
+use clap::Parser;
+use cli::Args;
+
+fn main() {
+ let args = Args::parse();
+}