@@ -17,25 +17,49 @@ fn make_case_insensitive_and_normalized_env(
17
17
. collect ( ) ;
18
18
let normalized_env = env
19
19
. 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.
21
25
. filter_map ( |( k, v) | Some ( ( k. to_str ( ) ?, v. to_str ( ) ?) ) )
22
26
. map ( |( k, _) | ( k. to_uppercase ( ) . replace ( "-" , "_" ) , k. to_owned ( ) ) )
23
27
. collect ( ) ;
24
28
( case_insensitive_env, normalized_env)
25
29
}
26
30
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.
27
43
#[ derive( Debug ) ]
28
44
pub struct Env {
29
45
/// A snapshot of the process's environment variables.
30
46
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.
35
57
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.
38
61
/// For example, this might hold a pair `("PATH", "Path")`.
62
+ /// Currently only supports UTF-8 keys and values.
39
63
case_insensitive_env : HashMap < String , String > ,
40
64
}
41
65
@@ -125,6 +149,18 @@ impl Env {
125
149
///
126
150
/// This is intended for use in private methods of `Config`,
127
151
/// 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.
128
164
pub ( super ) fn get_str ( & self , key : impl AsRef < OsStr > ) -> Option < & str > {
129
165
self . env . get ( key. as_ref ( ) ) . and_then ( |s| s. to_str ( ) )
130
166
}
@@ -133,14 +169,15 @@ impl Env {
133
169
///
134
170
/// This is intended for use in private methods of `Config`,
135
171
/// and does not check for env key case mismatch.
172
+ /// See the docstring of [`Env::get_str`] for more context.
136
173
pub ( super ) fn contains_key ( & self , key : impl AsRef < OsStr > ) -> bool {
137
174
self . env . contains_key ( key. as_ref ( ) )
138
175
}
139
176
140
177
/// Looks up a normalized `key` in the `normalized_env`.
141
178
/// Returns the corresponding (non-normalized) env key if it exists, else `None`.
142
179
///
143
- /// This is used by ` Config::check_environment_key_mismatch` .
180
+ /// This is used by [`super:: Config::check_environment_key_case_mismatch`] .
144
181
pub ( super ) fn get_normalized ( & self , key : & str ) -> Option < & str > {
145
182
self . normalized_env . get ( key) . map ( |s| s. as_ref ( ) )
146
183
}
0 commit comments