use std::ffi::OsStr;
#[cfg(windows)]
use std::os::windows::ffi::OsStrExt;
#[cfg(windows)]
const CSTR_EQUAL: i32 = 2;
#[cfg(windows)]
#[link(name = "kernel32")]
unsafe extern "system" {
#[link_name = "CompareStringOrdinal"]
fn compare_string_ordinal(
left: *const u16,
left_len: i32,
right: *const u16,
right_len: i32,
ignore_case: i32,
) -> i32;
}
#[cfg(not(windows))]
pub(crate) fn env_key_eq(left: &OsStr, right: &OsStr) -> bool {
left == right
}
#[cfg(windows)]
pub(crate) fn env_key_eq(left: &OsStr, right: &OsStr) -> bool {
let left = left.encode_wide().collect::<Vec<_>>();
let right = right.encode_wide().collect::<Vec<_>>();
let Ok(left_len) = i32::try_from(left.len()) else {
return false;
};
let Ok(right_len) = i32::try_from(right.len()) else {
return false;
};
let comparison =
unsafe { compare_string_ordinal(left.as_ptr(), left_len, right.as_ptr(), right_len, 1) };
if comparison == 0 {
log::debug!(
"failed to compare Windows environment variable names; treating keys as distinct"
);
}
comparison == CSTR_EQUAL
}