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)))]
6
compile_error!("You can't enable both async-std & tokio features at once");
7
#[cfg(all(not(feature = "tokio"), not(feature = "async-std"), not(doc)))]
8
compile_error!("You have to enable either tokio or async-std feature");
9
#[cfg(all(all(feature = "native_crypto", feature = "openssl_crypto"), not(doc)))]
10
compile_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
))]
16
compile_error!("You have to enable either openssl_crypto or native_crypto feature");
17

            
18
use std::collections::HashMap;
19

            
20
mod error;
21
mod key;
22
mod mac;
23
mod migration;
24

            
25
#[cfg(feature = "unstable")]
26
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
27
pub use key::Key;
28
#[cfg(not(feature = "unstable"))]
29
pub(crate) use key::Key;
30
pub use mac::Mac;
31

            
32
#[cfg(not(feature = "unstable"))]
33
mod crypto;
34
#[cfg(feature = "unstable")]
35
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
36
pub mod crypto;
37
pub mod dbus;
38
pub mod file;
39

            
40
mod keyring;
41
mod secret;
42

            
43
pub use ashpd;
44
#[cfg(feature = "schema")]
45
#[cfg_attr(docsrs, doc(cfg(feature = "schema")))]
46
pub use error::SchemaError;
47
pub use error::{Error, Result};
48
pub use keyring::{Item, Keyring};
49
pub use migration::migrate;
50
#[cfg(feature = "schema")]
51
#[cfg_attr(docsrs, doc(cfg(feature = "schema")))]
52
pub use oo7_macros::SecretSchema;
53
pub use secret::{ContentType, Secret};
54
pub 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.
60
pub 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.
65
pub const CONTENT_TYPE_ATTRIBUTE: &str = "xdg:content-type";
66

            
67
/// An item/collection attributes.
68
pub trait AsAttributes {
69
    fn as_attributes(&self) -> HashMap<String, String>;
70

            
71
32
    fn hash(&self, key: &Key) -> Vec<(String, std::result::Result<Mac, crate::crypto::Error>)> {
72
34
        self.as_attributes()
73
            .into_iter()
74
98
            .map(|(k, v)| (k, crypto::compute_mac(v.as_bytes(), key)))
75
            .collect()
76
    }
77
}
78

            
79
macro_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
41
            fn as_attributes(&self) -> std::collections::HashMap<String, String> {
87
38
                self.iter()
88
108
                    .map(|(k, v)| (k.as_ref().to_string(), v.as_ref().to_string()))
89
37
                    .collect()
90
            }
91
        }
92

            
93
        impl<K, V> AsAttributes for &$rust_type
94
        where
95
            K: AsRef<str>,
96
            V: AsRef<str>,
97
        {
98
2
            fn as_attributes(&self) -> std::collections::HashMap<String, String> {
99
2
                self.iter()
100
6
                    .map(|(k, v)| (k.as_ref().to_string(), v.as_ref().to_string()))
101
2
                    .collect()
102
            }
103
        }
104
    };
105
}
106

            
107
impl_as_attributes!([(K, V)]);
108
impl_as_attributes!(HashMap<K, V>);
109
impl_as_attributes!(std::collections::BTreeMap<K, V>);
110
impl_as_attributes!(Vec<(K, V)>);
111

            
112
impl<K, V, const N: usize> AsAttributes for [(K, V); N]
113
where
114
    K: AsRef<str>,
115
    V: AsRef<str>,
116
{
117
40
    fn as_attributes(&self) -> HashMap<String, String> {
118
42
        self.iter()
119
122
            .map(|(k, v)| (k.as_ref().to_string(), v.as_ref().to_string()))
120
            .collect()
121
    }
122
}
123

            
124
// Implementation for references to arrays
125
impl<K, V, const N: usize> AsAttributes for &[(K, V); N]
126
where
127
    K: AsRef<str>,
128
    V: AsRef<str>,
129
{
130
4
    fn as_attributes(&self) -> HashMap<String, String> {
131
4
        self.iter()
132
12
            .map(|(k, v)| (k.as_ref().to_string(), v.as_ref().to_string()))
133
            .collect()
134
    }
135
}