Skip to main content

ProxyConfig

Struct ProxyConfig 

Source
#[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
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§effective: ProxyMode

Resolved 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. That is the difference sources alone cannot express, and until this field existed the only record of it was a log line — so a consumer built without the tracing feature had none at all.

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, which is what makes a watcher deliver the snapshot where a degradation appears or clears. Excluding it would be worse than merely quiet: the watcher’s equality skip keeps the snapshot it already holds, so a degradation that healed would be reported for the rest of the watcher’s life.

§captured_at: SystemTime

Capture time; excluded from equality.

Implementations§

Source§

impl ProxyConfig

Source

pub fn new( effective: ProxyMode, sources: Vec<(ProxyConfigSource, ProxyMode)>, ) -> Self

Build a snapshot stamped with now.

Source

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.

Source

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.

Source

pub fn from_source(source: ProxyConfigSource, mode: ProxyMode) -> Self

Snapshot whose effective value comes from exactly one source.

Source

pub fn direct() -> Self

“No proxy” with no sources.

Source

pub fn source(&self, source: ProxyConfigSource) -> Option<&ProxyMode>

Mode for a specific source, if consulted.

Source

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.

What the fold does depends on the environment’s shape. ProxyEnv::is_configured separates the first shape from the other two; what separates those is whether anything was dropped, which ProxyEnv::rejected and ProxyEnv::bypass’s own rejections answer.

  • Configured — it takes the rank precedence asks for. A no_proxy with no proxy variable beside it is this shape, and ProxyEnv::to_mode turns it into Direct: under BeforeSystem it does not add a bypass to the OS proxy, it outranks that proxy and every host resolves direct. The error is toward bypassing more than the caller listed, never toward proxying a host they asked to exclude.
  • Present but specifying nothing — appended to sources and never made effective, so a typo cannot mask the OS. Where every *_proxy value was malformed, ProxyEnv::to_mode answers Manual and the drops come back out of source. Where instead a no_proxy lost every entry it held, to_mode answers Direct, 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 on ProxyEnv::bypass().rejected.
  • Specifying nothing and dropping nothingself is returned untouched. Usually that means the variables are unset, but a no_proxy that 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. Silently sending the scheme whose value was typed wrong straight out is the failure this crate exists to make visible.

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: the result is only as fresh as its stalest half. 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());

Trait Implementations§

Source§

impl Clone for ProxyConfig

Source§

fn clone(&self) -> ProxyConfig

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ProxyConfig

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ProxyConfig

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Eq for ProxyConfig

Source§

impl PartialEq for ProxyConfig

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more