Files
notfiles/crates/notsecrets/src/sources/prompt.rs
Joseph O'Brien aadb1570a3 refactor: formalize FileStore and IdentitySource ports in notfiles
- Create FileStore trait in crates/notfiles/src/ports.rs capturing all file I/O
  operations (read, write, rename, remove, metadata, symlink, etc.)
- Create FileStoreImpl adapter in crates/notfiles/src/adapters/fs.rs wrapping std::fs
- Update linker.rs State::load/save and link_package/unlink_package to accept
  FileStore parameter for dependency injection
- Create IdentitySource port in crates/notsecrets/src/ports.rs
- Move IdentitySource trait from sources/mod.rs to ports.rs, maintain backward
  compatibility via re-export
- Update all source implementations to import from ports
- Update lib.rs in both crates to re-export ports
- Pass FileStoreImpl through call chain in main.rs and lib.rs public API

Maintains 100% backward compatible public API; FileStore dependency is internal.
2026-04-12 16:35:53 -04:00

29 lines
891 B
Rust

use crate::error::AgeError;
use crate::identities::Identity;
use crate::identities::scrypt::ScryptIdentity;
use crate::ports::IdentitySource;
pub struct PromptSource;
impl IdentitySource for PromptSource {
fn name(&self) -> &str {
"prompt"
}
fn load(&self) -> Result<Box<dyn Identity>, AgeError> {
let passphrase = rpassword::prompt_password("Enter age passphrase: ").map_err(|e| {
AgeError::SourceError {
name: self.name().to_string(),
source: anyhow::anyhow!("could not read passphrase: {e}"),
}
})?;
if passphrase.trim().is_empty() {
return Err(AgeError::SourceError {
name: self.name().to_string(),
source: anyhow::anyhow!("empty passphrase entered"),
});
}
Ok(Box::new(ScryptIdentity::new(passphrase)))
}
}