1use crate::file::FileBackend;
4use crate::inject::{CredentialMetadata, CredentialValue, InjectedCredential, InjectionShape};
5use crate::vault::VaultError;
6
7#[cfg(target_os = "macos")]
8use crate::keychain::KeychainBackend;
9
10#[cfg(target_os = "linux")]
11use crate::keyring::SecretServiceBackend;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum BackendKind {
16 Keychain,
17 SecretService,
18 File,
19}
20
21impl std::fmt::Display for BackendKind {
22 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23 match self {
24 BackendKind::Keychain => write!(f, "keychain"),
25 BackendKind::SecretService => write!(f, "secret-service"),
26 BackendKind::File => write!(f, "file"),
27 }
28 }
29}
30
31pub enum VaultBackend {
34 #[cfg(target_os = "macos")]
35 Keychain(KeychainBackend),
36 #[cfg(target_os = "linux")]
37 SecretService(SecretServiceBackend),
38 File(FileBackend),
39}
40
41impl VaultBackend {
42 pub fn kind(&self) -> BackendKind {
43 match self {
44 #[cfg(target_os = "macos")]
45 VaultBackend::Keychain(_) => BackendKind::Keychain,
46 #[cfg(target_os = "linux")]
47 VaultBackend::SecretService(_) => BackendKind::SecretService,
48 VaultBackend::File(_) => BackendKind::File,
49 }
50 }
51
52 pub async fn store(
53 &self,
54 tool: &str,
55 key: &str,
56 value: CredentialValue,
57 shape: InjectionShape,
58 ) -> Result<(), VaultError> {
59 match self {
60 #[cfg(target_os = "macos")]
61 VaultBackend::Keychain(b) => b.store(tool, key, value, shape).await,
62 #[cfg(target_os = "linux")]
63 VaultBackend::SecretService(b) => b.store(tool, key, value, shape).await,
64 VaultBackend::File(b) => b.store(tool, key, value, shape).await,
65 }
66 }
67
68 pub async fn get(&self, tool: &str, key: &str) -> Result<InjectedCredential, VaultError> {
69 match self {
70 #[cfg(target_os = "macos")]
71 VaultBackend::Keychain(b) => b.get(tool, key).await,
72 #[cfg(target_os = "linux")]
73 VaultBackend::SecretService(b) => b.get(tool, key).await,
74 VaultBackend::File(b) => b.get(tool, key).await,
75 }
76 }
77
78 pub async fn delete(&self, tool: &str, key: &str) -> Result<(), VaultError> {
79 match self {
80 #[cfg(target_os = "macos")]
81 VaultBackend::Keychain(b) => b.delete(tool, key).await,
82 #[cfg(target_os = "linux")]
83 VaultBackend::SecretService(b) => b.delete(tool, key).await,
84 VaultBackend::File(b) => b.delete(tool, key).await,
85 }
86 }
87
88 pub async fn list(&self, tool: Option<&str>) -> Result<Vec<CredentialMetadata>, VaultError> {
89 match self {
90 #[cfg(target_os = "macos")]
91 VaultBackend::Keychain(b) => b.list(tool).await,
92 #[cfg(target_os = "linux")]
93 VaultBackend::SecretService(b) => b.list(tool).await,
94 VaultBackend::File(b) => b.list(tool).await,
95 }
96 }
97}