@@ -46,9 +46,26 @@ pub struct EnvKey {
4646 utf16 : Vec < u16 > ,
4747}
4848
49- // Windows environment variables preserve their case but comparisons use
50- // simplified case folding. So we call `CompareStringOrdinal` to get the OS to
51- // perform the comparison.
49+ // Comparing Windows environment variable keys[1] are behaviourally the
50+ // composition of two operations[2]:
51+ //
52+ // 1. Case-fold both strings. This is done using a language-independent
53+ // uppercase mapping that's unique to Windows (albeit based on data from an
54+ // older Unicode spec). It only operates on individual UTF-16 code units so
55+ // surrogates are left unchanged. This uppercase mapping can potentially change
56+ // between Windows versions.
57+ //
58+ // 2. Perform an ordinal comparison of the strings. A comparison using ordinal
59+ // is just a comparison based on the numerical value of each UTF-16 code unit[3].
60+ //
61+ // Because the case-folding mapping is unique to Windows and not guaranteed to
62+ // be stable, we ask the OS to compare the strings for us. This is done by
63+ // calling `CompareStringOrdinal`[4] with `bIgnoreCase` set to `TRUE`.
64+ //
65+ // [1] https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings#choosing-a-stringcomparison-member-for-your-method-call
66+ // [2] https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings#stringtoupper-and-stringtolower
67+ // [3] https://docs.microsoft.com/en-us/dotnet/api/system.stringcomparison?view=net-5.0#System_StringComparison_Ordinal
68+ // [4] https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-comparestringordinal
5269impl Ord for EnvKey {
5370 fn cmp ( & self , other : & Self ) -> cmp:: Ordering {
5471 unsafe {
@@ -84,6 +101,8 @@ impl PartialEq for EnvKey {
84101 }
85102}
86103
104+ // Environment variable keys should preserve their original case even though
105+ // they are compared using a caseless string mapping.
87106impl From < OsString > for EnvKey {
88107 fn from ( k : OsString ) -> Self {
89108 EnvKey { utf16 : k. encode_wide ( ) . collect ( ) , os_string : k }
0 commit comments