🔨 Moves to pass-cli json output format

Signed-off-by: Ash Svitan <selfsigned-ash@proton.me>
This commit is contained in:
2026-04-30 15:08:48 +02:00
parent eea8204fe2
commit 4337534f1a
4 changed files with 146 additions and 94 deletions
Generated
+81 -42
View File
@@ -2,47 +2,19 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 4 version = 4
[[package]]
name = "aho-corasick"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
dependencies = [
"memchr",
]
[[package]]
name = "bit-set"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
dependencies = [
"bit-vec",
]
[[package]]
name = "bit-vec"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
[[package]] [[package]]
name = "bitwarden-proton-sync" name = "bitwarden-proton-sync"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"fancy-regex", "serde",
"serde_json",
] ]
[[package]] [[package]]
name = "fancy-regex" name = "itoa"
version = "0.18.0" version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1e1dacd0d2082dfcf1351c4bdd566bbe89a2b263235a2b50058f1e130a47277" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
dependencies = [
"bit-set",
"regex-automata",
"regex-syntax",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
@@ -51,18 +23,85 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]] [[package]]
name = "regex-automata" name = "proc-macro2"
version = "0.4.14" version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [ dependencies = [
"aho-corasick", "unicode-ident",
"memchr",
"regex-syntax",
] ]
[[package]] [[package]]
name = "regex-syntax" name = "quote"
version = "0.8.10" version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "syn"
version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
+2 -1
View File
@@ -4,4 +4,5 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
fancy-regex = "0.18.0" serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.149"
+6 -5
View File
@@ -8,15 +8,16 @@ const ENV_VAR_DEFAULT_VAULT: &str = "PASS_VAULT";
fn main() -> Result<(), Error> { fn main() -> Result<(), Error> {
pass::check_pass()?; pass::check_pass()?;
let vaults = pass::get_vaults()?; let vaults = pass::get_vaults().vaults;
if vaults.len() <= 0 { if vaults.len() <= 0 {
return Err(Error::new(ErrorKind::Other, "No vaults found")); return Err(Error::new(ErrorKind::Other, "No vaults found"));
} }
let vault_names = vaults.iter().map(|vault| vault.name.clone()).collect::<Vec<String>>();
let vault; let vault;
match env::var(ENV_VAR_DEFAULT_VAULT) { match env::var(ENV_VAR_DEFAULT_VAULT) {
Ok(default_vault) => { Ok(default_vault) => {
if vaults.contains(&default_vault) { if vault_names.contains(&default_vault) {
vault = default_vault; vault = default_vault;
} else { } else {
return Err(Error::new( return Err(Error::new(
@@ -26,7 +27,7 @@ fn main() -> Result<(), Error> {
} }
} }
Err(_) => { Err(_) => {
vault = vaults.get(0).unwrap().clone(); vault = vault_names.get(0).unwrap().clone();
println!( println!(
"No default vault found (you can set it with {}), using {}...", "No default vault found (you can set it with {}), using {}...",
ENV_VAR_DEFAULT_VAULT, vault ENV_VAR_DEFAULT_VAULT, vault
@@ -34,8 +35,8 @@ fn main() -> Result<(), Error> {
} }
}; };
let items = pass::get_items(&vault); let items = pass::get_items(&vault).items;
println!("{:?}", items); println!("{:?}", items[0]);
return Ok(()); return Ok(());
} }
+57 -46
View File
@@ -1,10 +1,58 @@
use crate::sh; use crate::sh;
use fancy_regex::{Regex, RegexBuilder};
use std::io::{Error, ErrorKind}; use std::io::{Error, ErrorKind};
use serde::Deserialize;
const EXECUTABLE: &str = "pass-cli"; const EXECUTABLE: &str = "pass-cli";
const VAULT_NAME_REGEX: &str = r"(?<=- \[.{88}\]: ).*";
const ITEM_NAME_REGEX: &str = r"(?<=- \[.{88}\]: ).*(?= )"; #[derive(Deserialize, Debug)]
pub struct Vaults {
pub vaults: Vec<Vault>
}
#[derive(Deserialize, Debug)]
pub struct Vault {
pub name: String,
pub vault_id: String,
pub share_id: String
}
#[derive(Deserialize, Debug)]
pub struct Items {
pub items: Vec<Item>
}
#[derive(Deserialize, Debug)]
pub struct Item {
pub id: String,
pub share_id: String,
pub vault_id: String,
pub content: ItemContent,
pub state: String,
pub create_time: String,
pub modify_time: String
}
#[derive(Deserialize, Debug)]
pub struct ItemContent {
pub title: String,
pub note: String,
pub item_uuid: String,
pub content: ItemContentContent,
}
#[derive(Deserialize, Debug)]
pub struct ItemContentContent {
pub Login: Option<ItemLogin>
}
#[derive(Deserialize, Debug)]
pub struct ItemLogin {
pub email: String,
pub username: String,
pub password: String,
pub urls: Vec<String>,
pub totp_uri: String
}
pub fn check_pass() -> Result<(), Error> { pub fn check_pass() -> Result<(), Error> {
let which = sh::sh(format!("which {}", EXECUTABLE)); let which = sh::sh(format!("which {}", EXECUTABLE));
@@ -26,49 +74,12 @@ pub fn check_pass() -> Result<(), Error> {
return Ok(()); return Ok(());
} }
pub fn get_vaults() -> Result<Vec<String>, Error> { pub fn get_vaults() -> Vaults {
let re = Regex::new(VAULT_NAME_REGEX).unwrap(); let vaults_raw = sh::sh(format!("{} vault list --output json", EXECUTABLE));
let vaults_raw = sh::sh(format!("{} vault list", EXECUTABLE)); return serde_json::from_str(vaults_raw.as_str()).expect("Couldn't parse JSON");
let matches = re.find_iter(vaults_raw.as_str());
let mut vaults = Vec::<String>::new();
for each in matches {
if let Err(_) = each {
continue;
}
let each = each.unwrap();
let vault = each.as_str();
if !vault.is_empty() {
vaults.push(vault.to_string());
}
}
return Ok(vaults);
} }
pub fn get_items(vault: &String) -> Result<Vec<String>, Error> { pub fn get_items(vault: &String) -> Items {
let re = RegexBuilder::new(ITEM_NAME_REGEX) let items_raw = sh::sh(format!("{} item list {} --output json", EXECUTABLE, vault));
.multi_line(false) return serde_json::from_str(items_raw.as_str()).expect("Couldn't parse JSON");
.build()
.unwrap();
let items_raw = sh::sh(format!("{} item list {}", EXECUTABLE, vault));
let matches = re.find_iter(items_raw.as_str());
let mut items = Vec::<String>::new();
for each in matches {
if let Err(_) = each {
continue;
}
let each = each.unwrap();
let item = each.as_str();
if !item.is_empty() {
items.push(item.to_string());
}
}
return Ok(items);
} }