use crate::password::Password;
#[derive(Debug, PartialEq)]
pub(crate) struct Autotype(Vec<String>);
impl From<Autotype> for Vec<String> {
fn from(value: Autotype) -> Self {
value.0
}
}
impl From<(String, Password)> for Autotype {
fn from(value: (String, Password)) -> Self {
let tokens: Vec<&str> = value.0.split(" ").filter(|line| !line.is_empty()).collect();
let params = translate(tokens, value.1);
Self(params)
}
}
fn translate(tokens: Vec<&str>, password: Password) -> Vec<String> {
let mut params = Vec::new();
for token in tokens {
match token {
":tab" => {
params.push("-k".into());
params.push("Tab".into());
}
":enter" => {
params.push("-k".into());
params.push("Return".into());
}
token => {
let key = token.strip_prefix(':').unwrap_or(token).to_string();
match password.get(&key) {
Some(value) => {
params.push(value);
}
None => params.push(token.to_string()),
}
}
}
}
params
}
#[cfg(test)]
mod test {
use super::*;
use indoc::indoc;
use pretty_assertions::assert_eq;
#[test]
fn test_translate() {
let password = password();
let autotype = Autotype::from((
password
.get(&"autotype".into())
.expect("autotype wasn't found"),
password,
));
assert_eq!(
vec![
"me@example.com",
"-k",
"Tab",
"Very Secret Password",
"-k",
"Return"
],
Vec::from(autotype)
);
}
fn password() -> Password {
let doc = indoc! {"
Very Secret Password
---
user: me@example.com
url: https://bank.example.com/login
autotype: user :tab :password :enter
"}
.to_string();
doc.parse().expect("Password wasn't created")
}
}