Skip to main content

oo7/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![deny(rustdoc::broken_intra_doc_links)]
3#![doc = include_str!("../README.md")]
4#![deny(unsafe_code)]
5#[cfg(all(all(feature = "tokio", feature = "async-std"), not(doc)))]
6compile_error!("You can't enable both async-std & tokio features at once");
7#[cfg(all(not(feature = "tokio"), not(feature = "async-std"), not(doc)))]
8compile_error!("You have to enable either tokio or async-std feature");
9#[cfg(all(all(feature = "native_crypto", feature = "openssl_crypto"), not(doc)))]
10compile_error!("You can't enable both openssl_crypto & native_crypto features at once");
11#[cfg(all(
12    not(feature = "native_crypto"),
13    not(feature = "openssl_crypto"),
14    not(doc)
15))]
16compile_error!("You have to enable either openssl_crypto or native_crypto feature");
17
18use std::collections::HashMap;
19
20mod error;
21mod key;
22mod mac;
23mod migration;
24
25#[cfg(feature = "unstable")]
26#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
27pub use key::Key;
28#[cfg(not(feature = "unstable"))]
29pub(crate) use key::Key;
30pub use mac::Mac;
31
32#[cfg(not(feature = "unstable"))]
33mod crypto;
34#[cfg(feature = "unstable")]
35#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
36pub mod crypto;
37pub mod dbus;
38pub mod file;
39
40mod keyring;
41mod secret;
42
43pub use ashpd;
44#[cfg(feature = "schema")]
45#[cfg_attr(docsrs, doc(cfg(feature = "schema")))]
46pub use error::SchemaError;
47pub use error::{Error, Result};
48pub use keyring::{Item, Keyring};
49pub use migration::migrate;
50#[cfg(feature = "schema")]
51#[cfg_attr(docsrs, doc(cfg(feature = "schema")))]
52pub use oo7_macros::SecretSchema;
53pub use secret::{ContentType, Secret};
54pub use zbus;
55
56/// A schema attribute.
57///
58/// Currently the key, is not really used but would allow
59/// to map a Rust struct of simple types to an item attributes with type check.
60pub const XDG_SCHEMA_ATTRIBUTE: &str = "xdg:schema";
61
62/// A content type attribute.
63///
64/// Defines the type of the secret stored in the item.
65pub const CONTENT_TYPE_ATTRIBUTE: &str = "xdg:content-type";
66
67/// An item/collection attributes.
68pub trait AsAttributes {
69    fn as_attributes(&self) -> HashMap<String, String>;
70
71    fn hash(&self, key: &Key) -> Vec<(String, std::result::Result<Mac, crate::crypto::Error>)> {
72        self.as_attributes()
73            .into_iter()
74            .map(|(k, v)| (k, crypto::compute_mac(v.as_bytes(), key)))
75            .collect()
76    }
77}
78
79macro_rules! impl_as_attributes {
80    ($rust_type:ty) => {
81        impl<K, V> AsAttributes for $rust_type
82        where
83            K: AsRef<str>,
84            V: AsRef<str>,
85        {
86            fn as_attributes(&self) -> std::collections::HashMap<String, String> {
87                self.iter()
88                    .map(|(k, v)| (k.as_ref().to_string(), v.as_ref().to_string()))
89                    .collect()
90            }
91        }
92
93        impl<K, V> AsAttributes for &$rust_type
94        where
95            K: AsRef<str>,
96            V: AsRef<str>,
97        {
98            fn as_attributes(&self) -> std::collections::HashMap<String, String> {
99                self.iter()
100                    .map(|(k, v)| (k.as_ref().to_string(), v.as_ref().to_string()))
101                    .collect()
102            }
103        }
104    };
105}
106
107impl_as_attributes!([(K, V)]);
108impl_as_attributes!(HashMap<K, V>);
109impl_as_attributes!(std::collections::BTreeMap<K, V>);
110impl_as_attributes!(Vec<(K, V)>);
111
112impl<K, V, const N: usize> AsAttributes for [(K, V); N]
113where
114    K: AsRef<str>,
115    V: AsRef<str>,
116{
117    fn as_attributes(&self) -> HashMap<String, String> {
118        self.iter()
119            .map(|(k, v)| (k.as_ref().to_string(), v.as_ref().to_string()))
120            .collect()
121    }
122}
123
124// Implementation for references to arrays
125impl<K, V, const N: usize> AsAttributes for &[(K, V); N]
126where
127    K: AsRef<str>,
128    V: AsRef<str>,
129{
130    fn as_attributes(&self) -> HashMap<String, String> {
131        self.iter()
132            .map(|(k, v)| (k.as_ref().to_string(), v.as_ref().to_string()))
133            .collect()
134    }
135}