refactor(cli): move parse helpers into parse.rs

This commit is contained in:
adlee-was-taken
2026-05-06 18:23:37 -04:00
parent 272b6a3845
commit 52400230e0
2 changed files with 43 additions and 40 deletions

View File

@@ -16,6 +16,7 @@ use anyhow::{bail, Context, Result};
use clap::{CommandFactory, Parser, Subcommand}; use clap::{CommandFactory, Parser, Subcommand};
use clap_complete::{generate, Shell}; use clap_complete::{generate, Shell};
use crate::parse::{base32_decode_lenient, guess_mime, parse_month_year};
use crate::prompt::{prompt, prompt_keep, prompt_keep_opt, prompt_optional, prompt_secret, prompt_yesno}; use crate::prompt::{prompt, prompt_keep, prompt_keep_opt, prompt_optional, prompt_secret, prompt_yesno};
#[derive(Parser)] #[derive(Parser)]
@@ -915,46 +916,6 @@ fn build_totp_item(
Ok(item) Ok(item)
} }
fn parse_month_year(s: &str) -> Result<relicario_core::MonthYear> {
// Accepts MM/YYYY or MM-YYYY or MM/YY.
let (m_str, y_str) = s.split_once(['/', '-'])
.ok_or_else(|| anyhow::anyhow!("expected MM/YYYY"))?;
let month: u8 = m_str.parse().context("invalid month")?;
let year: u16 = if y_str.len() == 2 {
2000 + y_str.parse::<u16>().context("invalid 2-digit year")?
} else {
y_str.parse().context("invalid year")?
};
Ok(relicario_core::MonthYear { month, year })
}
fn guess_mime(filename: &str) -> String {
let lower = filename.to_ascii_lowercase();
match lower.rsplit_once('.').map(|(_, ext)| ext).unwrap_or("") {
"pdf" => "application/pdf",
"png" => "image/png",
"jpg" | "jpeg" => "image/jpeg",
"txt" => "text/plain",
"json" => "application/json",
_ => "application/octet-stream",
}.to_string()
}
fn base32_decode_lenient(s: &str) -> Result<Vec<u8>> {
let cleaned: String = s.chars()
.filter(|c| !c.is_whitespace())
.collect::<String>()
.to_ascii_uppercase()
.trim_end_matches('=')
.to_string();
let padded = {
let rem = cleaned.len() % 8;
if rem == 0 { cleaned } else { format!("{}{}", cleaned, "=".repeat(8 - rem)) }
};
data_encoding::BASE32.decode(padded.as_bytes())
.map_err(|e| anyhow::anyhow!("invalid base32: {e}"))
}
fn commit_paths(vault: &crate::session::UnlockedVault, message: &str, paths: &[&str]) -> Result<()> { fn commit_paths(vault: &crate::session::UnlockedVault, message: &str, paths: &[&str]) -> Result<()> {
let mut args: Vec<&str> = vec!["add"]; let mut args: Vec<&str> = vec!["add"];
args.extend_from_slice(paths); args.extend_from_slice(paths);

View File

@@ -3,3 +3,45 @@
//! Phase 7 of the CLI restructure migrates these to `relicario-core` and //! Phase 7 of the CLI restructure migrates these to `relicario-core` and
//! turns this file into a thin re-export shim. They live here for now so //! turns this file into a thin re-export shim. They live here for now so
//! the Phase 1 relocation stays mechanical. //! the Phase 1 relocation stays mechanical.
use anyhow::{Context, Result};
pub(crate) fn parse_month_year(s: &str) -> Result<relicario_core::MonthYear> {
// Accepts MM/YYYY or MM-YYYY or MM/YY.
let (m_str, y_str) = s.split_once(['/', '-'])
.ok_or_else(|| anyhow::anyhow!("expected MM/YYYY"))?;
let month: u8 = m_str.parse().context("invalid month")?;
let year: u16 = if y_str.len() == 2 {
2000 + y_str.parse::<u16>().context("invalid 2-digit year")?
} else {
y_str.parse().context("invalid year")?
};
Ok(relicario_core::MonthYear { month, year })
}
pub(crate) fn guess_mime(filename: &str) -> String {
let lower = filename.to_ascii_lowercase();
match lower.rsplit_once('.').map(|(_, ext)| ext).unwrap_or("") {
"pdf" => "application/pdf",
"png" => "image/png",
"jpg" | "jpeg" => "image/jpeg",
"txt" => "text/plain",
"json" => "application/json",
_ => "application/octet-stream",
}.to_string()
}
pub(crate) fn base32_decode_lenient(s: &str) -> Result<Vec<u8>> {
let cleaned: String = s.chars()
.filter(|c| !c.is_whitespace())
.collect::<String>()
.to_ascii_uppercase()
.trim_end_matches('=')
.to_string();
let padded = {
let rem = cleaned.len() % 8;
if rem == 0 { cleaned } else { format!("{}{}", cleaned, "=".repeat(8 - rem)) }
};
data_encoding::BASE32.decode(padded.as_bytes())
.map_err(|e| anyhow::anyhow!("invalid base32: {e}"))
}