Skip to main content

SupervisorConfig

Struct SupervisorConfig 

Source
pub struct SupervisorConfig {
Show 14 fields pub ssas_per_request: usize, pub allow_dynamic_ssa_batches: bool, pub max_failed_cycles: usize, pub max_ssa_delivery_time: Duration, pub commitment_recommit_interval: Duration, pub max_deposit_wait: Duration, pub max_recovery_idle: Duration, pub max_recovery_time: Duration, pub max_off_front_share_fraction: f64, pub min_share_order_sample: u64, pub max_predeposit_packets: u64, pub max_served_without_progress: u64, pub tombstone_retention_window: Duration, pub fill: PixFillConfig,
}
Expand description

Configuration for the SessionPixSupervisor.

Reachable from a node’s configuration file as incoming_session_pix_config.supervision. The fields interact — with each other and with the reconstructor’s own lifetimes — so a set of them is only meaningful as a whole; that is what validate_pix_supervision checks, and the node’s config validator runs it at load time.

A worked set of values, and what each field defends against, is written out under “Configuration” in the supervision module documentation — the module is crate-private, so it is named rather than linked here.

Fields§

§ssas_per_request: usize

Maximum number of SSAs the Exit may ask the Entry to commit to in one SsaRequest.

With allow_dynamic_ssa_batches, Session admission picks the smallest batch no larger than this value whose total quota is inside the Exit’s accepted range. With dynamic batching disabled, this remains the exact batch size, preserving the original fixed-batch behavior. Batching amortizes the request round trip over several deposit cycles. It lives here rather than beside the other Exit settings because the supervisor acts on the selected value: it allocates the indices and scales both deadlines below by this factor.

Two things it costs, both linear in the value:

  • Up to two batches can own live reconstructor state — worst case ≈41 MiB per cycle at the profiled dimensions, per hopr_protocol_pix::peak_cycle_bytes. That cost is reserved up front against IncomingSessionPixConfig::max_live_cycle_bytes; the supervisor enforces the two-generation/full-cycle bound before allocating, so this value directly divides the number of PIX Sessions the node will admit.
  • The unfunded exposure within one batch: every cycle is initially requested unfunded, so the commitment and deposit deadlines cover this many SSA quotas rather than one. The front-aware service gate still grants only the current cycle’s bounded predeposit allowance.

Must not exceed the peer Entry’s max_ssas_per_request. The batch size is not negotiated — the options word in the most significant 64 bits of StartSession.additional_data is fully allocated (PIX dimensions and SURB balancer target), and its least significant 64 bits are not yet used for this, so the Entry does not advertise its cap and the Exit cannot learn it. An Entry that finds a batch too large refuses it in full and replies with an UnacceptablePixParams SessionError, which closes the Session on both sides in about a round trip. Every such Session is still lost; the reply only makes the failure immediate and attributable instead of surfacing as a commitment timeout.

Range-checked by validate_pix_supervision and clamped where it is read, so it can never exceed MAX_SSA_BATCH_SIZE.

Default: 1, which reproduces the unbatched exchange byte-for-byte.

§allow_dynamic_ssa_batches: bool

Whether Session admission may derive a smaller SSA batch from the Entry’s offered quota.

When enabled, the Exit tries batch sizes from one through ssas_per_request and selects the first whose total quota is inside IncomingSessionPixConfig::quota_range. If none fits, the Session is refused with UnacceptablePixParams. Choosing the smallest fit limits Entry work, deposits, Exit memory, and the chance of exceeding the Entry’s unadvertised max_ssas_per_request cap.

When disabled, the offered per-SSA quota itself must be inside quota_range, and the Exit requests exactly ssas_per_request SSAs, matching the behavior before dynamic batching.

Default: true.

§max_failed_cycles: usize

Cycles this Session may lose without recovering them before it is closed. The next one closes it.

Counted over the whole Session, not per batch, because a retired cycle leaves no trace on its siblings: without a cumulative count an Entry can lose one cycle per batch forever while a single funded sibling keeps the Session alive, paying for a fraction of what it is served.

Only reachable with ssas_per_request > 1. At the shipping batch of one the failing cycle is always the last one standing, and that closes the Session before this is ever consulted — so nothing changes at the defaults.

A recovered cycle never counts: it leaves through tombstone expiry, not through the failure path.

Default: 1 — one lost cycle is survivable, which is what the retire-and-hand-on-the-successor -gate path exists for, and a second is not.

§max_ssa_delivery_time: Duration

Maximum time to wait for the SSA to be fully committed.

Together with max_deposit_wait this bounds how long a Session may be served unincentivized: the Entry has to be able to deliver its SSA commitment before it can be asked to pay for it.

Multiplied by ssas_per_request when the deadline is armed: a batch asks the Entry for that many commitment sets in answer to one request, and all of their clocks start together, so holding each to a single cycle’s budget would fail an Entry that is answering in order.

Default: 20 s.

§commitment_recommit_interval: Duration

How long a partially delivered commitment may go quiet before the missing parts are re-requested.

The Entry’s answer to an SsaRequest is not one message but hundreds of them, and the Exit can use none of it until every one has landed — so a single lost packet used to cost the whole Session on max_ssa_delivery_time, typically after the Entry had already been told to fund the cycle’s deposit address. This is the timer that repairs it: on expiry the Exit asks the Entry to re-send the polynomial commitments it never received.

An idle timer, armed and re-armed by each arriving commitment message, so it measures silence rather than elapsed time and the first ask cannot land in the middle of the burst. It is only ever armed once something has arrived: a commitment nothing was delivered for has no scope to name, and there is nothing the Exit could ask for.

It bounds nothing on its own — max_ssa_delivery_time remains the absolute deadline, so the unincentivized exposure of a cycle is unchanged however often this fires. How many asks a cycle makes is bounded by count rather than by this interval: MAX_COMMITMENT_RETRANSMISSIONS, which is also exactly how many the Entry will answer, so shortening this buys promptness and never a flood of wasted packets.

Default: 3 s — well clear of the time a full burst takes to arrive, and short enough that a repair completes several times over inside the delivery deadline.

§max_deposit_wait: Duration

Maximum time to wait for a deposit after the commitment is verifiable.

Also multiplied by ssas_per_request. Each cycle’s clock starts at its own commitment, which staggers them somewhat — but a batch’s commitments arrive back-to-back while an Entry funding them serially finishes the last one that many deposits later, so the stagger does not cover it.

Default: 60 s.

§max_recovery_idle: Duration

Maximum idle time during recovery when service is being consumed.

Gated on service consumption — if no packets were served, the timer re-arms instead of closing.

Default: 60 s.

§max_recovery_time: Duration

Absolute per-SSA recovery deadline (immutable once set).

This is a resource backstop (session slot + reconstructor memory), not the anti-drip mechanism. The service-gated idle rule is.

§Why four hours

It has to leave a whole cycle at the dimensions the node accepts time to complete, but that floor is far below four hours: ~61 min with fill at its default ceiling, ~2 min without fill at MAX_ASSUMED_SESSION_PACKET_RATE. A cycle cut short is worth nothing, since the SSA is the sum of every polynomial’s constant term, so the margin is cheap.

What sets the value is the rest of what it does. With fill enabled it is the idle tariff: an idle Session’s cycle is finished at finish_fraction of it, three hours, which needs 64 packets/s for the widest accepted quota. And it keeps this instrument far enough out that max_recovery_idle is what actually binds.

The clock starts when the cycle reaches the paid transport front. That is deliberately later than merely becoming the earliest unrecovered record: the predecessor’s buffered surplus tail can still occupy ~4096 packets, over a minute for a slow Session, and remains bounded by the predecessor’s original hard clock. Starting the successor at the FIFO boundary prevents that pipeline delay from being charged twice. A funded cycle that reaches the front and is never served is still caught.

HoprProtocolConfig::validate checks this against the dimensions the node will actually accept, so a raised quota_range that outgrows it is refused at load rather than discovered one closed Session at a time.

Default: 4 hours.

§max_off_front_share_fraction: f64

Largest share of recovery progress that may land on a cycle other than the one at the front of the batch, as a fraction of all progress since that cycle took the front.

§What it defends

A batch only de-risks the Exit if its cycles are served one at a time, so that recovering the first pays for the traffic that earned it. An Entry that instead spread a batch’s shares across all ssas_per_request cycles could take ssas_per_request × quota of service while leaving every cycle short of recovery — and a cycle short of recovery pays nothing at all, since the SSA is the sum of every polynomial’s constant term. That turns the batch knob from cost-neutral into an n-fold amplifier of unpaid traffic.

Nothing else sees it. The service gate and max_recovery_idle both measure the absence of progress, and a spreading Entry makes progress on every cycle continuously — including the front one, whose idle timer it therefore keeps refreshing. It simply never finishes one.

§Why a fraction and not a count

Out-of-order arrival is not an Entry property. SURBs cross the mixnet outbound and their acknowledgements cross it again inbound, so arrival order is a permutation of emission order whose width is roughly delay_range × packet rate. An absolute tolerance would therefore have to be re-derived every time the mixer is reconfigured, and — being cumulative — would drift into closing honest Sessions given enough cycle boundaries.

A ratio has neither problem: a permutation of bounded width is a vanishing fraction of a growing window, so widening delay_range cannot move it, and the denominator grows with the numerator so nothing accumulates. It is also independent of packet rate (both terms scale together, so unlike a wall-clock bound it implies no throughput floor), of loss (which hits every cycle alike), and of surplus_shares — which matters even now that the surplus is negotiated rather than Entry-private. The Exit knows the budget, not the spend: how many of a cycle’s emitted shares turn out to be useful depends on the loss the Entry actually met, so no expected shares-per-packet ratio follows from the parameter. Comparing the batch’s cycles against each other cancels it.

§The value

A conforming Entry sits at ~0: with emission clamped to one cycle (hopr_protocol_pix::SHARE_EMISSION_WINDOW) the only off-front progress is boundary reordering. Spreading across n cycles gives (n − 1) / n — 0.5 at two cycles, 0.67 at three. 0.25 separates those with room on both sides.

It bounds rather than eliminates: an Entry may divert up to this fraction and stay legal, so worst-case unpaid exposure becomes ~1 / (1 − f) cycles instead of n. Alternating — serving the front cycle honestly, then dumping on later ones — buys nothing, because the accounting only resets when the front cycle completes, which means it was paid for.

Default: 0.25.

§min_share_order_sample: u64

Progress that must accumulate before max_off_front_share_fraction is judged at all, in useful shares.

A sample-size floor, not a tolerance: it does not bound how much a cheat can extract — the fraction does that — it only refuses to convict on thin evidence.

Sized by the one case that would otherwise produce a false positive: a cycle made unrecoverable by loss. A polynomial that loses more than surplus_shares of its shares can never reach its threshold, so its cycle stops progressing while later ones continue, and the off-front fraction climbs to 1.0. That cycle is not something to close a Session over — it stops progressing, its service-gated max_recovery_idle deadline expires, it is retired, and the accounting resets on the new front. The sample floor only has to outlast that window: ~181 shares/s, the per-Session rate this was sized at, over 60 s is ~10 900, and 16 384 covers up to ~273 shares/s.

Unlike an absolute tolerance this does not have to grow with Session length or track the mixer configuration — it is a floor on evidence, evaluated once and then continuously.

Very large values can make this rule effectively inert for a Session. To disable share-order enforcement intentionally, prefer max_off_front_share_fraction = 1.0. No fixed upper bound is enforced because the accounting window can span multiple successor batches before the front advances.

Default: 16384 shares.

§max_predeposit_packets: u64

Cap on the provisional predeposit service budget.

This buys the application an exchange while the current front cycle’s deposit confirms on chain; it is not needed for the Session to become fundable, so it is a latency-versus-exposure dial rather than a correctness requirement. The initial front starts with this allowance, and it is restored for an unfunded successor after a paid front leaves the front, whether by recovery or a tolerated failure. Retiring an unfunded front does not grant it again.

Zero is supported and means strict prepay: the Exit answers nothing until a sufficient deposit is confirmed. Everything on the path to funding — the SsaRequest, the Entry’s commitment, the deposit itself, and the SURB keep-alive stream — bypasses the egress gate, so a zero budget stalls the application without ever stalling the funding handshake. Deliberately not rejected by validate_pix_supervision for that reason, unlike max_served_without_progress, where zero would wedge a Session that has already paid.

The effective budget is min(target_useful_shares - 1, max_predeposit_packets), so this value is the binding one at any realistic set of PIX dimensions.

Default: 10000 packets.

§max_served_without_progress: u64

Maximum packets served without a single share coming back, before the gate blocks further service as a defence-in-depth backstop.

A ceiling enforced by ServiceGate::acquire while the current front is funded. A crate::HoprSessionInPixEvent::RecoveryProgress snapshot resets it only for that funded front. The sole recovered predecessor temporarily remains that paid front while its per-polynomial negotiated remainder drains; progress on an unfunded, queued, older, or over-budget cycle does not grant service.

Those events now follow shares_seen rather than useful_shares, which is what makes a flat 2048 safe at any dimensions. Keyed on useful shares, this had to exceed surplus x min(polys, SHARE_EMISSION_WINDOW) — 4096 at the shipped dimensions, twice this value — because a conforming Entry emits a whole window’s surplus in one contiguous run during which no share is useful. The gate parked the writer partway through, and a parked writer spends no SURBs, so nothing could arrive to release it. See SsaRecoveryProgress::shares_seen.

What it bounds now is genuine silence, and that is rate-independent: it is a count of packets, so unlike max_recovery_idle it implies no throughput floor.

Default: 2048 packets.

§tombstone_retention_window: Duration

How long to retain recovered-SSA diagnostic records and observer ownership.

Must be >= the reconstructor’s max_ack_await_time. The compact paid-tail receipt is separate and may outlive this record; expiring a tombstone therefore does not truncate a FIFO drain.

Default: 30 s.

§fill: PixFillConfig

How the Exit keeps a funded cycle on course for its own deadline when the application is quiet.

Every other field above is a rule for stopping. This one is the single rule for going, and it exists because the deadlines cannot be met by an idle Session: a funded cycle only recovers once its whole emission has ridden back to the Entry, so at production dimensions a Session averaging under ~46 return packets/s over a cycle loses its deposit to max_recovery_time — which is every idle or light client.

See PixFillConfig for what it costs and what it is bounded by.

Trait Implementations§

Source§

impl Clone for SupervisorConfig

Source§

fn clone(&self) -> SupervisorConfig

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 SupervisorConfig

Source§

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

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

impl Default for SupervisorConfig

Source§

fn default() -> Self

Return SupervisorConfig { ssas_per_request: 1, allow_dynamic_ssa_batches: true, max_failed_cycles: 1, max_ssa_delivery_time: Duration::from_secs(20), commitment_recommit_interval: Duration::from_secs(3), max_deposit_wait: Duration::from_secs(60), max_recovery_idle: Duration::from_secs(60), max_recovery_time: Duration::from_secs(14400), max_off_front_share_fraction: 0.25, min_share_order_sample: 16384, max_predeposit_packets: 10000, max_served_without_progress: 2048, tombstone_retention_window: Duration::from_secs(30), fill: Default::default() }

Source§

impl<'de> Deserialize<'de> for SupervisorConfig

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for SupervisorConfig

Source§

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

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

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

Inequality operator !=. Read more
Source§

impl Serialize for SupervisorConfig

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for SupervisorConfig

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
§

impl<'de, T> BorrowedRpcObject<'de> for T
where T: RpcBorrow<'de> + RpcSend,

§

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

§

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
§

impl<T> Conv for T

§

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

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

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

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

§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FutureExt for T

§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
§

impl<T> Instrument for T

§

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

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

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
§

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

§

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
§

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
§

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
§

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
§

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
§

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.
§

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.
§

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.
§

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.
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

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

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
§

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

§

impl<'de, T> RpcBorrow<'de> for T
where T: Deserialize<'de> + Debug + Send + Sync + Unpin,

§

impl<T> RpcObject for T
where T: RpcSend + RpcRecv,

§

impl<T> RpcRecv for T
where T: DeserializeOwned + Debug + Send + Sync + Unpin + 'static,

§

impl<T> RpcSend for T
where T: Serialize + Clone + Debug + Send + Sync + Unpin,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

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

Immutable access to a value. Read more
§

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

Mutable access to a value. Read more
§

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
§

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
§

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
§

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
§

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
§

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
§

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

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

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

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

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.
§

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.
§

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.
§

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.
§

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.
§

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
§

impl<T> TryConv for T

§

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 = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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