#[non_exhaustive]pub struct ProxyConfig {
pub effective: ProxyMode,
pub sources: Vec<(ProxyConfigSource, ProxyMode)>,
pub fallbacks: Vec<ProxyConfigSource>,
pub captured_at: SystemTime,
}Expand description
Point-in-time system proxy snapshot.
Backend-built: sources descending precedence, effective = first (or Direct).
ProxyConfig::from_ordered_sources enforces that invariant; ProxyConfig::new
remains available for caller-defined resolved configurations. PartialEq ignores
captured_at.
let a = ProxyConfig::from_source(ProxyConfigSource::Registry, ProxyMode::Direct);
let mut b = a.clone();
b.captured_at = SystemTime::UNIX_EPOCH;
assert_eq!(a, b);Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.effective: ProxyModeResolved mode after platform precedence.
sources: Vec<(ProxyConfigSource, ProxyMode)>Descending precedence; backend snapshots: first wins (or Direct if empty).
fallbacks: Vec<ProxyConfigSource>Sources that were consulted, could not be read, and were left out of sources
rather than failing the whole read.
A source absent from both lists was not configured; a source listed here is one
the machine may well be configured with, whose value this read did not learn.
sources alone cannot express that. The log line that also records
it reaches only a consumer built with the tracing feature.
Backend snapshots only: nothing here is derived from the modes, so
ProxyConfig::new and the constructors below leave it empty and
ProxyConfig::with_fallbacks is what fills it in.
Unlike captured_at this is compared by PartialEq, so a watcher delivers
the snapshot where a degradation appears or clears. Excluded, it would leave the
watcher’s equality skip holding the snapshot it already has, so a degradation that
healed would be reported for the rest of the watcher’s life.
captured_at: SystemTimeCapture time; excluded from equality.
Implementations§
Source§impl ProxyConfig
impl ProxyConfig
Sourcepub fn new(
effective: ProxyMode,
sources: Vec<(ProxyConfigSource, ProxyMode)>,
) -> Self
pub fn new( effective: ProxyMode, sources: Vec<(ProxyConfigSource, ProxyMode)>, ) -> Self
Build a snapshot stamped with now.
Sourcepub fn with_fallbacks(self, fallbacks: Vec<ProxyConfigSource>) -> Self
pub fn with_fallbacks(self, fallbacks: Vec<ProxyConfigSource>) -> Self
Record the sources this read could not learn the value of.
See fallbacks. Takes the whole list rather than appending, so
a backend that assembles one alongside its sources hands it over in one place.
Sourcepub fn from_ordered_sources(
sources: Vec<(ProxyConfigSource, ProxyMode)>,
) -> Self
pub fn from_ordered_sources( sources: Vec<(ProxyConfigSource, ProxyMode)>, ) -> Self
Build a snapshot from sources already ordered by descending precedence.
The first mode becomes effective; an empty list becomes
ProxyMode::Direct. The source order and every losing source are preserved.
Sourcepub fn from_source(source: ProxyConfigSource, mode: ProxyMode) -> Self
pub fn from_source(source: ProxyConfigSource, mode: ProxyMode) -> Self
Snapshot whose effective value comes from exactly one source.
Sourcepub fn source(&self, source: ProxyConfigSource) -> Option<&ProxyMode>
pub fn source(&self, source: ProxyConfigSource) -> Option<&ProxyMode>
Mode for a specific source, if consulted.
Sourcepub fn with_env(self, env: &ProxyEnv, precedence: EnvPrecedence) -> Self
pub fn with_env(self, env: &ProxyEnv, precedence: EnvPrecedence) -> Self
Fold the process environment into this snapshot as one more source.
The environment enters whole: one entry in sources, ranked
against the OS sources rather than merged into them slot by slot. Setting only
http_proxy therefore does not leave the OS’s https proxy in place; the winning
source answers for every scheme, and an environment with no https entry resolves
https to direct. all_proxy is how the environment covers the schemes it did not
name.
The fold depends on the environment’s shape. ProxyEnv::is_configured separates
the first shape from the other two; whether anything was dropped separates those,
and ProxyEnv::rejected and ProxyEnv::bypass’s own rejections answer that.
- Configured: it takes the rank
precedenceasks for. Ano_proxywith no proxy variable beside it is this shape, andProxyEnv::to_modeturns it intoDirect: underBeforeSystemit does not add a bypass to the OS proxy, it outranks that proxy and every host resolves direct. The result errs toward bypassing more than the caller listed, never toward proxying a host they asked to exclude. - Present but specifying nothing: appended to
sourcesand never madeeffective, so a typo cannot mask the OS. Where every*_proxyvalue was malformed,ProxyEnv::to_modeanswersManualand the drops come back out ofsource. Where instead ano_proxylost every entry it held,to_modeanswersDirect, which has nowhere to hold an exclusion list: the entry records only that the environment was there and lost something, and the text of the drop stays onProxyEnv::bypass().rejected. - Specifying nothing and dropping nothing:
selfis returned untouched. Usually that means the variables are unset, but ano_proxythat parses to no rules and no rejections (no_proxy=,no_proxy=",") lands here too: it was set, and the snapshot keeps no evidence that it was.
Being configured and having dropped something are not exclusive. no_proxy=.corp
beside an http_proxy that does not parse is configured (the bypass list is the
configuration), so it takes the rank, and the dropped scheme rides in with it:
http then answers Error::ProxyEntryUnusable
instead of falling through to the OS proxy or to direct.
Fold an environment in once. A second with_env can leave a second
Env entry in sources, and source
answers with whichever is first, which the second environment’s shape decides as
much as the precedence does.
captured_at becomes the older of the two reads, except in the
third shape, where nothing is folded in. effective is otherwise left alone,
including where that leaves it disagreeing with sources[0].
let env = ProxyEnv::from_vars([("http_proxy", "http://env.corp:3128")]).unwrap();
let os = ProxyConfig::from_source(ProxyConfigSource::Registry, ProxyMode::Direct);
let merged = os.with_env(&env, EnvPrecedence::BeforeSystem);
assert!(matches!(merged.effective, ProxyMode::Manual { .. }));
assert_eq!(merged.sources.len(), 2);
assert!(merged.source(ProxyConfigSource::Registry).is_some());