1//! Secrets.
2
3use ::log::info;
4use whiskers_ports::{Lookup, SecretName, SecretValue, Secrets, run_ready};
5
6/// Runs every secrets law. `with` makes a store holding exactly these raw values (a name not listed
7/// is not set at all).
8pub fn secrets<S: Secrets>(with: &impl Fn(&[(SecretName, &str)]) -> S) {
9    info!("conformance: secrets");
10    secrets_absent_empty_and_present_are_three_things(with);
11    secrets_are_trimmed_and_independent(with);
12}
13
14pub fn secrets_absent_empty_and_present_are_three_things<S: Secrets>(with: &impl Fn(&[(SecretName, &str)]) -> S) {
15    let s = with(&[(SecretName::VoiceKey, ""), (SecretName::VoiceId, "  \n"), (SecretName::JevKey, "k")]);
16    assert_eq!(run_ready(s.get(SecretName::VoiceKey)).unwrap(), Lookup::Empty, "set to nothing");
17    assert_eq!(run_ready(s.get(SecretName::VoiceId)).unwrap(), Lookup::Empty, "set to only whitespace");
18    assert_eq!(run_ready(s.get(SecretName::JevKey)).unwrap(), Lookup::Present(SecretValue::new("k")));
19    let none = with(&[]);
20    for name in SecretName::ALL {
21        assert_eq!(run_ready(none.get(name)).unwrap(), Lookup::Absent, "{name} was never set");
22    }
23}
24
25pub fn secrets_are_trimmed_and_independent<S: Secrets>(with: &impl Fn(&[(SecretName, &str)]) -> S) {
26    let s = with(&[(SecretName::VoiceKey, " sk-1 \n")]);
27    assert_eq!(run_ready(s.get(SecretName::VoiceKey)).unwrap(), Lookup::Present(SecretValue::new("sk-1")), "a pasted newline is not part of the key");
28    assert_eq!(run_ready(s.get(SecretName::VoiceId)).unwrap(), Lookup::Absent, "setting one name sets no other");
29}