pub(crate) struct GuardSet {
guards: ByRelayIds<Guard>,
sample: Vec<GuardId>,
confirmed: Vec<GuardId>,
primary: Vec<GuardId>,
active_filter: GuardFilter,
filter_is_restrictive: bool,
primary_guards_invalidated: bool,
unknown_fields: HashMap<String, JsonValue>,
}
Expand description
A set of sampled guards, along with various orderings on subsets of the sample.
Every guard in a GuardSet
is considered to be “sampled”: that
is, selected from a network directory at some point in the past.
The guards in the sample are ordered (roughly) by the time at
which they were added. This list is persistent.
Any guard which we’ve successfully used at least once is considered “confirmed”. Confirmed guards are ordered (roughly) by the time at which we first used them. This list is persistent.
The guards which we would prefer to use are called “primary”. Primary guards are ordered from most- to least-preferred. This list is not persistent, and is re-derived as needed.
These lists together define a “preference order”. All primary guards come first in preference order. Then come the non-primary confirmed guards, in their confirmed order. Finally come the non-primary, non-confirmed guards, in their sampled order.
Fields§
§guards: ByRelayIds<Guard>
Map from identities to guards, for every guard in this sample.
The key for each entry is a set of identities which we have good (trustworthy-enough) reason to link together.
When we connect to a guard we require it to demonstrate that it has all of these identities; and we do pinning, so that we note down the other identities we discover it has, with the intent that we will require them in future.
§Sources of linkage:
-
If we connect to a relay and it proves a set of identities, that necessarily will include at least the ones we have already. We can add any other identities we have discovered. Justification: the owners of the old ids have made a statement (via the connection protocols) that these other ids are also theirs, and should be required in future.
-
If we obtain a (full) descriptor for a relay, and check the self-signatures by all the identities we have already, we can add any other identities listed in the descriptor. Justification: the owners of the old ids have made an explicit statement that these other ids are also theirs, and should be required in future.
-
For a relay in the netdir, if the netdir links some ids together, we can combine the entries. Justification: the netdir is authoritative for netdir-based relays.
-
For a configured bridge, if our configuration links some identities, we must insist on all those identities. So we combine them.
§Handling of conflicting entries:
ByRelayIds
will implicitly delete conflicting entries,
simply forgetting about them.
This is OK for netdir relays, since we do not expect this to occur in practice.
For bridges, conflicts may in fact occur, since bridge lines are not issued by a single authority, and should be afforded limited trust.
-
If the configuration contains bridge lines that mutually conflict, affected bridge lines should be disregarded, or the configuration rejected.
-
If the configuration contains information which is inconsistent with our past experience, we should discard the past experiences which aren’t reconcilable with the configuration.
-
We may discover a linkage which demonstrates that the configuration is wrong: for example, two bridge lines for identities X and Y, but in fact there is only one bridge with both identities. In this situation it is OK to effectively disregard some the configuration entries which are at variance with reality, maybe with a warning, but keeping at least one of every usable id set (actually existing bridge) would be good.
sample: Vec<GuardId>
Identities of all the guards in the sample, in sample order.
This contains the same elements as the keys of guards
confirmed: Vec<GuardId>
Identities of all the confirmed guards in the sample, in confirmed order.
This contains a subset of the values in sample
.
primary: Vec<GuardId>
Identities of all the primary guards, in preference order (from best to worst).
This contains a subset of the values in sample
.
active_filter: GuardFilter
Currently active filter that restricts which guards we can use.
Note that all of the lists above (with the exception of primary
)
can hold guards that the filter doesn’t permit. This behavior
is meant to give good security behavior in the presence of filters
that change over time.
filter_is_restrictive: bool
If true, the active filter is “very restrictive”.
primary_guards_invalidated: bool
Set to ‘true’ whenever something changes that would force us to call ‘select_primary_guards()’, and cleared whenever we call it.
unknown_fields: HashMap<String, JsonValue>
Fields from the state file that was used to make this GuardSet
that
this version of Arti doesn’t understand.
Implementations§
Source§impl GuardSet
impl GuardSet
Sourcefn inner_lengths(&self) -> (usize, usize, usize, usize)
fn inner_lengths(&self) -> (usize, usize, usize, usize)
Return the lengths of the different elements of the guard set.
Used to report bugs or corruption in consistency.
Sourcefn fix_consistency(&mut self)
fn fix_consistency(&mut self)
Remove all elements from this GuardSet
that ought to be referenced by
another element, but which are not.
This method only removes corrupted elements and updates IDs in the ID
list (possibly adding new IDs); it doesn’t add guards or other data.
It won’t do anything if the GuardSet
is well-formed.
Sourcefn assert_consistency(&mut self)
fn assert_consistency(&mut self)
Assert that this GuardSet
is internally consistent.
Incidentally fixes the consistency of this GuardSet
if needed.
Sourcepub(crate) fn get(&self, id: &GuardId) -> Option<&Guard>
pub(crate) fn get(&self, id: &GuardId) -> Option<&Guard>
Return the guard that has every identity in id
, if any.
Sourcepub(crate) fn set_filter(&mut self, filter: GuardFilter, restrictive: bool)
pub(crate) fn set_filter(&mut self, filter: GuardFilter, restrictive: bool)
Replace the filter used by this GuardSet
with filter
.
Removes all primary guards that the filter doesn’t permit.
If restrictive
is true, this filter is treated as “extremely restrictive”.
Sourcepub(crate) fn filter(&self) -> &GuardFilter
pub(crate) fn filter(&self) -> &GuardFilter
Return the current filter for this GuardSet
.
Sourcepub(crate) fn copy_ephemeral_status_into_newly_loaded_state(
&mut self,
other: GuardSet,
)
pub(crate) fn copy_ephemeral_status_into_newly_loaded_state( &mut self, other: GuardSet, )
Copy non-persistent status from every guard shared with other
.
This is used as part of our reload process when we don’t own our state
files, and we’re reloading in order to find out what the other Arti
instance thinks the guards are. At that point, self
is the set of
guards that we just loaded from state, and other
is our old guards,
which we are using only for their status information.
Sourcefn get_state(&self) -> GuardSample<'_>
fn get_state(&self) -> GuardSample<'_>
Return a serializable state object that can be stored to disk to capture the current state of this GuardSet.
Sourcefn from_state(state: GuardSample<'_>) -> Self
fn from_state(state: GuardSample<'_>) -> Self
Reconstruct a guard state from its serialized representation.
Sourcepub(crate) fn contains(&self, id: &GuardId) -> Result<bool, &GuardId>
pub(crate) fn contains(&self, id: &GuardId) -> Result<bool, &GuardId>
Return Ok(true)
if id
is definitely a member of this set, and
Ok(false)
if it is definitely not a member.
If we cannot tell, it’s because there is a guard in this sample that has
a subset of the IDs in id
. In that case, we return
Err(guard_ident)
, where guard_ident
is the identity of that guard.
Sourcepub(crate) fn extend_sample_as_needed<U: Universe>(
&mut self,
now: SystemTime,
params: &GuardParams,
dir: &U,
) -> ExtendedStatus
pub(crate) fn extend_sample_as_needed<U: Universe>( &mut self, now: SystemTime, params: &GuardParams, dir: &U, ) -> ExtendedStatus
If there are not enough filter-permitted usable guards in this sample (according to the current active filter), then add more, up to the limits allowed by the parameters.
This is the only function that adds new guards to the sample.
Guards always start out un-confirmed.
Return true if any guards were added.
Sourcefn extend_sample_inner<U: Universe>(
&mut self,
now: SystemTime,
params: &GuardParams,
dir: &U,
) -> bool
fn extend_sample_inner<U: Universe>( &mut self, now: SystemTime, params: &GuardParams, dir: &U, ) -> bool
Implementation helper for extend_sample_as_needed.
§Complications
For spec conformance, we only consider our filter when selecting new guards if the filter is “very restrictive”. That makes it possible that this function will add fewer filter-permitted guards than we had wanted. Because of that, this is a separate function, and extend_sample_as_needed runs it in a loop until it returns false.
Sourcefn add_guard(&mut self, relay: Candidate, now: SystemTime, params: &GuardParams)
fn add_guard(&mut self, relay: Candidate, now: SystemTime, params: &GuardParams)
Add relay
as a new guard.
Does nothing if it is already a guard.
Sourcepub(crate) fn n_primary_without_id_info_in<U: Universe>(
&mut self,
universe: &U,
) -> usize
pub(crate) fn n_primary_without_id_info_in<U: Universe>( &mut self, universe: &U, ) -> usize
Return the number of our primary guards that are missing directory
information in universe
.
Note that “missing directory information” is not the same as “absent”: in this case, we are counting the primary guards where we cannot tell whether they appear in the universe or not because we have not yet downloaded their descriptors.
Sourcepub(crate) fn update_status_from_dir<U: Universe>(&mut self, dir: &U)
pub(crate) fn update_status_from_dir<U: Universe>(&mut self, dir: &U)
Update the status of every guard in this sample from a given source.
Sourcepub(crate) fn select_primary_guards(&mut self, params: &GuardParams)
pub(crate) fn select_primary_guards(&mut self, params: &GuardParams)
Re-build the list of primary guards.
Primary guards are chosen according to preference order over all the guards in the set, restricted by the current filter.
TODO: Enumerate all the times when this function needs to be called.
TODO: Make sure this is called enough.
Sourcepub(crate) fn expire_old_guards(
&mut self,
params: &GuardParams,
now: SystemTime,
)
pub(crate) fn expire_old_guards( &mut self, params: &GuardParams, now: SystemTime, )
Remove all guards which should expire now
, according to the settings
in params
.
Sourcefn reachable_sample_ids(&self) -> impl Iterator<Item = &GuardId>
fn reachable_sample_ids(&self) -> impl Iterator<Item = &GuardId>
Return an iterator over the Id for every Guard in the sample that is not known to be Unreachable.
Sourcefn preference_order_ids(&self) -> impl Iterator<Item = (ListKind, &GuardId)>
fn preference_order_ids(&self) -> impl Iterator<Item = (ListKind, &GuardId)>
Return an iterator that yields an element for every guard in this set, in preference order.
Each element contains a ListKind
that describes which list the
guard was in, and a &GuardId
that identifies the guard.
Note that this function will return guards that are not accepted by the current active filter: the caller must apply that filter if appropriate.
Sourcefn preference_order(&self) -> impl Iterator<Item = (ListKind, &Guard)> + '_
fn preference_order(&self) -> impl Iterator<Item = (ListKind, &Guard)> + '_
Like preference_order_ids
, but yields &Guard
instead of &GuardId
.
Sourcefn guard_is_primary(&self, guard_id: &GuardId) -> bool
fn guard_is_primary(&self, guard_id: &GuardId) -> bool
Return true if guard_id
is an identity subset for any primary guard in this set.
Sourcepub(crate) fn consider_all_retries(&mut self, now: Instant)
pub(crate) fn consider_all_retries(&mut self, now: Instant)
For every guard that has been marked as Unreachable
for too long,
mark it as Unknown
.
Sourcepub(crate) fn next_retry(&self, usage: &GuardUsage) -> Option<Instant>
pub(crate) fn next_retry(&self, usage: &GuardUsage) -> Option<Instant>
Return the earliest time at which any guard will be retriable.
Sourcepub(crate) fn mark_primary_guards_retriable(&mut self)
pub(crate) fn mark_primary_guards_retriable(&mut self)
Mark every Unreachable
primary guard as Unknown
.
Sourcepub(crate) fn all_primary_guards_are_unreachable(&mut self) -> bool
pub(crate) fn all_primary_guards_are_unreachable(&mut self) -> bool
Return true if all of our primary guards are currently marked unreachable.
Sourcepub(crate) fn mark_all_guards_retriable(&mut self)
pub(crate) fn mark_all_guards_retriable(&mut self)
Mark every Unreachable
guard as Unknown
.
Sourcepub(crate) fn record_attempt(&mut self, guard_id: &GuardId, now: Instant)
pub(crate) fn record_attempt(&mut self, guard_id: &GuardId, now: Instant)
Record that an attempt has begun to use the guard with
guard_id
.
Sourcepub(crate) fn record_success(
&mut self,
guard_id: &GuardId,
params: &GuardParams,
how: Option<ExternalActivity>,
now: SystemTime,
)
pub(crate) fn record_success( &mut self, guard_id: &GuardId, params: &GuardParams, how: Option<ExternalActivity>, now: SystemTime, )
Record that an attempt to use the guard with guard_id
has just
succeeded.
If how
is provided, it’s an operation from outside the crate that the
guard succeeded at doing.
Sourcepub(crate) fn record_failure(
&mut self,
guard_id: &GuardId,
how: Option<ExternalActivity>,
now: Instant,
)
pub(crate) fn record_failure( &mut self, guard_id: &GuardId, how: Option<ExternalActivity>, now: Instant, )
Record that an attempt to use the guard with guard_id
has just failed.
Sourcepub(crate) fn record_attempt_abandoned(&mut self, guard_id: &GuardId)
pub(crate) fn record_attempt_abandoned(&mut self, guard_id: &GuardId)
Record that an attempt to use the guard with guard_id
has
just been abandoned, without learning whether it succeeded or failed.
Sourcepub(crate) fn record_indeterminate_result(&mut self, guard_id: &GuardId)
pub(crate) fn record_indeterminate_result(&mut self, guard_id: &GuardId)
Record that an attempt to use the guard with guard_id
has
just failed in a way that we could not definitively attribute to
the guard.
Sourcepub(crate) fn record_skew(
&mut self,
guard_id: &GuardId,
observation: SkewObservation,
)
pub(crate) fn record_skew( &mut self, guard_id: &GuardId, observation: SkewObservation, )
Record that a given guard has told us about clock skew.
Sourcepub(crate) fn skew_observations(&self) -> impl Iterator<Item = &SkewObservation>
pub(crate) fn skew_observations(&self) -> impl Iterator<Item = &SkewObservation>
Return an iterator over all stored clock skew observations.
Sourcepub(crate) fn circ_usability_status(
&self,
guard_id: &GuardId,
usage: &GuardUsage,
params: &GuardParams,
now: Instant,
) -> Option<bool>
pub(crate) fn circ_usability_status( &self, guard_id: &GuardId, usage: &GuardUsage, params: &GuardParams, now: Instant, ) -> Option<bool>
Return whether the circuit manager can be allowed to use a
circuit with the guard_id
.
Return Some(bool)
if the circuit is usable, and None
if we
cannot yet be sure.
Sourcepub(crate) fn pick_guard(
&self,
sample_id: &GuardSetSelector,
usage: &GuardUsage,
params: &GuardParams,
now: Instant,
) -> Result<(ListKind, FirstHop), PickGuardError>
pub(crate) fn pick_guard( &self, sample_id: &GuardSetSelector, usage: &GuardUsage, params: &GuardParams, now: Instant, ) -> Result<(ListKind, FirstHop), PickGuardError>
Try to select a guard for a given usage
.
On success, returns the kind of guard that we got, and its filtered representation in a form suitable for use as a first hop.
Label the returned guard as having come from sample_id
.
Sourcefn pick_guard_id(
&self,
usage: &GuardUsage,
params: &GuardParams,
now: Instant,
) -> Result<(ListKind, GuardId), PickGuardError>
fn pick_guard_id( &self, usage: &GuardUsage, params: &GuardParams, now: Instant, ) -> Result<(ListKind, GuardId), PickGuardError>
Try to select a guard for a given usage
.
On success, returns the kind of guard that we got, and its identity.
Sourcepub(crate) fn descriptors_to_request(
&self,
now: Instant,
params: &GuardParams,
) -> Vec<&Guard>
Available on crate feature bridge-client
only.
pub(crate) fn descriptors_to_request( &self, now: Instant, params: &GuardParams, ) -> Vec<&Guard>
bridge-client
only.Return the guards whose bridge descriptors we should request, given our current configuration and status.
(The output of this function is not reasonable unless this is a Bridge sample.)
Trait Implementations§
Source§impl<'de> Deserialize<'de> for GuardSet
impl<'de> Deserialize<'de> for GuardSet
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl<'a> From<&'a GuardSet> for GuardSample<'a>
impl<'a> From<&'a GuardSet> for GuardSample<'a>
Source§impl<'a> From<GuardSample<'a>> for GuardSet
impl<'a> From<GuardSample<'a>> for GuardSet
Source§fn from(sample: GuardSample<'_>) -> Self
fn from(sample: GuardSample<'_>) -> Self
Auto Trait Implementations§
impl Freeze for GuardSet
impl RefUnwindSafe for GuardSet
impl Send for GuardSet
impl Sync for GuardSet
impl Unpin for GuardSet
impl UnwindSafe for GuardSet
Blanket Implementations§
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
, which can then be
downcast
into Box<dyn ConcreteType>
where ConcreteType
implements Trait
.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
, which can then be further
downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.§impl<T> DowncastSend for T
impl<T> DowncastSend for T
§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.