pub const FOR_UNTRUSTED_CALLER: u32 = 0x0000_0001;
pub const FOR_UNTRUSTED_DATA: u32 = 0x0000_0002;
pub const CATID_SAFE_FOR_SCRIPTING: &str = "{7DD95801-9882-11CF-9FA9-00AA006C42C4}";
pub const CATID_SAFE_FOR_INITIALIZING: &str = "{7DD95802-9882-11CF-9FA9-00AA006C42C4}";
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Asked {
Automation,
Persistence,
Other,
}
pub const fn supported(asked: Asked) -> u32 {
match asked {
Asked::Automation => FOR_UNTRUSTED_CALLER,
Asked::Persistence => FOR_UNTRUSTED_DATA,
Asked::Other => 0,
}
}
pub const fn accepts(supported: u32, mask: u32) -> bool {
mask & !supported == 0
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn each_kind_of_interface_gets_the_claim_that_matches_the_question() {
assert_eq!(supported(Asked::Automation), FOR_UNTRUSTED_CALLER);
assert_eq!(supported(Asked::Persistence), FOR_UNTRUSTED_DATA);
assert_eq!(
supported(Asked::Automation) & FOR_UNTRUSTED_DATA,
0,
"claiming safety for data on a scripting interface answers a question \
the host did not ask"
);
}
#[test]
fn an_interface_with_no_claim_offers_nothing() {
assert_eq!(supported(Asked::Other), 0);
assert!(!accepts(supported(Asked::Other), FOR_UNTRUSTED_CALLER));
}
#[test]
fn a_host_asking_for_what_is_offered_is_told_yes() {
let scripting = supported(Asked::Automation);
assert!(accepts(scripting, FOR_UNTRUSTED_CALLER));
assert!(accepts(scripting, 0), "asking for nothing always succeeds");
}
#[test]
fn a_host_asking_for_a_guarantee_that_was_never_offered_is_refused() {
let scripting = supported(Asked::Automation);
assert!(!accepts(scripting, FOR_UNTRUSTED_DATA));
assert!(!accepts(
scripting,
FOR_UNTRUSTED_CALLER | FOR_UNTRUSTED_DATA
));
assert!(!accepts(scripting, 0x8000_0000));
}
#[test]
fn a_host_switching_a_guarantee_off_is_not_an_error() {
assert!(accepts(supported(Asked::Automation), FOR_UNTRUSTED_CALLER));
}
#[test]
fn the_two_category_ids_are_distinct_and_well_formed() {
for catid in [CATID_SAFE_FOR_SCRIPTING, CATID_SAFE_FOR_INITIALIZING] {
assert_eq!(catid.len(), 38, "{catid} is not a braced GUID");
assert!(catid.starts_with('{') && catid.ends_with('}'));
assert_eq!(catid, catid.to_uppercase());
}
assert_ne!(CATID_SAFE_FOR_SCRIPTING, CATID_SAFE_FOR_INITIALIZING);
}
}