@@ -17,25 +17,49 @@ fn make_case_insensitive_and_normalized_env(
1717 . collect ( ) ;
1818 let normalized_env = env
1919 . iter ( )
20- // Only keep entries where both the key and value are valid UTF-8
20+ // Only keep entries where both the key and value are valid UTF-8,
21+ // since the config env vars only support UTF-8 keys and values.
22+ // Otherwise, the normalized map warning could incorrectly warn about entries that can't be
23+ // read by the config system.
24+ // Please see the docs for `Env` for more context.
2125 . filter_map ( |( k, v) | Some ( ( k. to_str ( ) ?, v. to_str ( ) ?) ) )
2226 . map ( |( k, _) | ( k. to_uppercase ( ) . replace ( "-" , "_" ) , k. to_owned ( ) ) )
2327 . collect ( ) ;
2428 ( case_insensitive_env, normalized_env)
2529}
2630
31+ /// A snapshot of the environment variables available to [`super::Config`].
32+ ///
33+ /// Currently, the [`Config`](super::Config) supports lookup of environment variables
34+ /// through two different means:
35+ ///
36+ /// - [`Config::get_env`](super::Config::get_env)
37+ /// and [`Config::get_env_os`](super::Config::get_env_os)
38+ /// for process environment variables (similar to [`std::env::var`] and [`std::env::var_os`]),
39+ /// - Typed Config Value API via [`Config::get`](super::Config::get).
40+ /// This is only available for `CARGO_` prefixed environment keys.
41+ ///
42+ /// This type contains the env var snapshot and helper methods for both APIs.
2743#[ derive( Debug ) ]
2844pub struct Env {
2945 /// A snapshot of the process's environment variables.
3046 env : HashMap < OsString , OsString > ,
31- /// A map from normalized (upper case and with "-" replaced by "_") env keys to the actual key
32- /// in the environment.
33- /// The "normalized" key is the format expected by Cargo.
34- /// This is used to warn users when env keys are not provided in this format.
47+ /// Used in the typed Config value API for warning messages when config keys are
48+ /// given in the wrong format.
49+ ///
50+ /// Maps from "normalized" (upper case and with "-" replaced by "_") env keys
51+ /// to the actual keys in the environment.
52+ /// The normalized format is the one expected by Cargo.
53+ ///
54+ /// This only holds env keys that are valid UTF-8, since [`super::ConfigKey`] only supports UTF-8 keys.
55+ /// In addition, this only holds env keys whose value in the environment is also valid UTF-8,
56+ /// since the typed Config value API only supports UTF-8 values.
3557 normalized_env : HashMap < String , String > ,
36- /// A map from uppercased env keys to the actual key in the environment.
37- /// This is relevant on Windows, where env keys are case-insensitive.
58+ /// Used to implement `get_env` and `get_env_os` on Windows, where env keys are case-insensitive.
59+ ///
60+ /// Maps from uppercased env keys to the actual key in the environment.
3861 /// For example, this might hold a pair `("PATH", "Path")`.
62+ /// Currently only supports UTF-8 keys and values.
3963 case_insensitive_env : HashMap < String , String > ,
4064}
4165
@@ -125,6 +149,18 @@ impl Env {
125149 ///
126150 /// This is intended for use in private methods of `Config`,
127151 /// and does not check for env key case mismatch.
152+ ///
153+ /// This is case-sensitive on Windows (even though environment keys on Windows are usually
154+ /// case-insensitive) due to an unintended regression in 1.28 (via #5552).
155+ /// This should only affect keys used for cargo's config-system env variables (`CARGO_`
156+ /// prefixed ones), which are currently all uppercase.
157+ /// We may want to consider rectifying it if users report issues.
158+ /// One thing that adds a wrinkle here is the unstable advanced-env option that *requires*
159+ /// case-sensitive keys.
160+ ///
161+ /// Do not use this for any other purposes.
162+ /// Use [`Env::get_env_os`] or [`Env::get_env`] instead, which properly handle case
163+ /// insensitivity on Windows.
128164 pub ( super ) fn get_str ( & self , key : impl AsRef < OsStr > ) -> Option < & str > {
129165 self . env . get ( key. as_ref ( ) ) . and_then ( |s| s. to_str ( ) )
130166 }
@@ -133,14 +169,15 @@ impl Env {
133169 ///
134170 /// This is intended for use in private methods of `Config`,
135171 /// and does not check for env key case mismatch.
172+ /// See the docstring of [`Env::get_str`] for more context.
136173 pub ( super ) fn contains_key ( & self , key : impl AsRef < OsStr > ) -> bool {
137174 self . env . contains_key ( key. as_ref ( ) )
138175 }
139176
140177 /// Looks up a normalized `key` in the `normalized_env`.
141178 /// Returns the corresponding (non-normalized) env key if it exists, else `None`.
142179 ///
143- /// This is used by ` Config::check_environment_key_mismatch` .
180+ /// This is used by [`super:: Config::check_environment_key_case_mismatch`] .
144181 pub ( super ) fn get_normalized ( & self , key : & str ) -> Option < & str > {
145182 self . normalized_env . get ( key) . map ( |s| s. as_ref ( ) )
146183 }
0 commit comments