Movatterモバイル変換


[0]ホーム

URL:


Docs.rs

tap/
tap.rs

1/*! # Point-Free Inspection23The standard library does not provide a way to view or modify an expression4without binding it to a name. This module provides extension methods that take5and return a value, allowing it to be temporarily bound without creating a new6`let`-statement in the enclosing scope.78The two main uses of these methods are to temporarily attach debugging9tracepoints to an expression without modifying its surrounding code, or to10temporarily mutate an otherwise-immutable object.1112For convenience, methods are available that will modify the *view* of the tapped13object that is passed to the effect function, by using the value’s14`Borrow`/`BorrowMut`, `AsRef`/`AsMut`, or `Index`/`IndexMut` trait15implementations. For example, the `Vec` collection has no `fn sort` method: this16is actually implemented on slices, to which `Vec` dereferences.1718```rust19use tap::tap::*;20# fn make_vec() -> Vec<i32> { vec![] }2122// taps take ordinary closures, which can use deref coercion23make_vec().tap_mut(|v| v.sort());24// `Vec<T>` implements `BorrowMut<[T]>`,25make_vec().tap_borrow_mut(<[_]>::sort);26// and `AsMut<[T]>`,27make_vec().tap_ref_mut(<[_]>::sort);28// and `DerefMut<Target = [T]>,29make_vec().tap_deref_mut(<[_]>::sort);30// but has no inherent method `sort`.31// make_vec().tap_mut(Vec::sort);32```33!*/3435usecore::{36borrow::{Borrow, BorrowMut},37ops::{Deref, DerefMut},38};3940/** Point-free value inspection and modification.4142This trait provides methods that permit viewing the value of an expression43without requiring a new `let` binding or any other alterations to the original44code other than insertion of the `.tap()` call.4546The methods in this trait do not perform any view conversions on the value they47receive; it is borrowed and passed directly to the effect argument.48**/49pub traitTap50where51Self: Sized,52{53/// Immutable access to a value.54///55/// This function permits a value to be viewed by some inspecting function56/// without affecting the overall shape of the expression that contains this57/// method call. It is useful for attaching assertions or logging points58/// into a multi-part expression.59///60/// # Examples61///62/// Here we use `.tap()` to attach logging tracepoints to each stage of a63/// value-processing pipeline.64///65/// ```rust66/// use tap::tap::Tap;67/// # struct Tmp;68/// # impl Tmp { fn process_value(self) -> Self { self } }69/// # fn make_value() -> Tmp { Tmp }70/// # macro_rules! log { ($msg:literal, $x:ident) => {{}}; }71///72/// let end = make_value()73///   // this line has no effect on the rest of the code74///   .tap(|v| log!("The produced value was: {}", v))75///   .process_value();76/// ```77#[inline(always)]78fntap(self, func:implFnOnce(&Self)) ->Self{79func(&self);80self81}8283/// Mutable access to a value.84///85/// This function permits a value to be modified by some function without86/// affecting the overall shape of the expression that contains this method87/// call. It is useful for attaching modifier functions that have an88/// `&mut Self -> ()` signature to an expression, without requiring an89/// explicit `let mut` binding.90///91/// # Examples92///93/// Here we use `.tap_mut()` to sort an array without requring multiple94/// bindings.95///96/// ```rust97/// use tap::tap::Tap;98///99/// let sorted = [1i32, 5, 2, 4, 3]100///   .tap_mut(|arr| arr.sort());101/// assert_eq!(sorted, [1, 2, 3, 4, 5]);102/// ```103///104/// Without tapping, this would be written as105///106/// ```rust107/// let mut received = [1, 5, 2, 4, 3];108/// received.sort();109/// let sorted = received;110/// ```111///112/// The mutable tap is a convenient alternative when the expression to113/// produce the collection is more complex, for example, an iterator114/// pipeline collected into a vector.115#[inline(always)]116fntap_mut(mutself, func:implFnOnce(&mutSelf)) ->Self{117func(&mutself);118self119}120121/// Immutable access to the `Borrow<B>` of a value.122///123/// This function is identcal to [`Tap::tap`], except that the effect124/// function recevies an `&B` produced by `Borrow::<B>::borrow`, rather than125/// an `&Self`.126///127/// [`Tap::tap`]: trait.Tap.html#method.tap128#[inline(always)]129fntap_borrow<B>(self, func:implFnOnce(&B)) ->Self130where131Self: Borrow<B>,132B:?Sized,133{134func(Borrow::<B>::borrow(&self));135self136}137138/// Mutable access to the `BorrowMut<B>` of a value.139///140/// This function is identical to [`Tap::tap_mut`], except that the effect141/// function receives an `&mut B` produced by `BorrowMut::<B>::borrow_mut`,142/// rather than an `&mut Self`.143///144/// [`Tap::tap_mut`]: trait.Tap.html#method.tap_mut145#[inline(always)]146fntap_borrow_mut<B>(mutself, func:implFnOnce(&mutB)) ->Self147where148Self: BorrowMut<B>,149B:?Sized,150{151func(BorrowMut::<B>::borrow_mut(&mutself));152self153}154155/// Immutable access to the `AsRef<R>` view of a value.156///157/// This function is identical to [`Tap::tap`], except that the effect158/// function receives an `&R` produced by `AsRef::<R>::as_ref`, rather than159/// an `&Self`.160///161/// [`Tap::tap`]: trait.Tap.html#method.tap162#[inline(always)]163fntap_ref<R>(self, func:implFnOnce(&R)) ->Self164where165Self: AsRef<R>,166R:?Sized,167{168func(AsRef::<R>::as_ref(&self));169self170}171172/// Mutable access to the `AsMut<R>` view of a value.173///174/// This function is identical to [`Tap::tap_mut`], except that the effect175/// function receives an `&mut R` produced by `AsMut::<R>::as_mut`, rather176/// than an `&mut Self`.177///178/// [`Tap::tap_mut`]: trait.Tap.html#method.tap_mut179#[inline(always)]180fntap_ref_mut<R>(mutself, func:implFnOnce(&mutR)) ->Self181where182Self: AsMut<R>,183R:?Sized,184{185func(AsMut::<R>::as_mut(&mutself));186self187}188189/// Immutable access to the `Deref::Target` of a value.190///191/// This function is identical to [`Tap::tap`], except that the effect192/// function receives an `&Self::Target` produced by `Deref::deref`, rather193/// than an `&Self`.194///195/// [`Tap::tap`]: trait.Tap.html#method.tap196#[inline(always)]197fntap_deref<T>(self, func:implFnOnce(&T)) ->Self198where199Self: Deref<Target = T>,200T:?Sized,201{202func(Deref::deref(&self));203self204}205206/// Mutable access to the `Deref::Target` of a value.207///208/// This function is identical to [`Tap::tap_mut`], except that the effect209/// function receives an `&mut Self::Target` produced by210/// `DerefMut::deref_mut`, rather than an `&mut Self`.211///212/// [`Tap::tap_mut`]: trait.Tap.html#method.tap_mut213#[inline(always)]214fntap_deref_mut<T>(mutself, func:implFnOnce(&mutT)) ->Self215where216Self: DerefMut + Deref<Target = T>,217T:?Sized,218{219func(DerefMut::deref_mut(&mutself));220self221}222223//  debug-build-only copies of the above methods224225/// Calls `.tap()` only in debug builds, and is erased in release builds.226#[inline(always)]227fntap_dbg(self, func:implFnOnce(&Self)) ->Self{228ifcfg!(debug_assertions) {229func(&self);230}231self232}233234/// Calls `.tap_mut()` only in debug builds, and is erased in release235/// builds.236#[inline(always)]237fntap_mut_dbg(mutself, func:implFnOnce(&mutSelf)) ->Self{238ifcfg!(debug_assertions) {239func(&mutself);240}241self242}243244/// Calls `.tap_borrow()` only in debug builds, and is erased in release245/// builds.246#[inline(always)]247fntap_borrow_dbg<B>(self, func:implFnOnce(&B)) ->Self248where249Self: Borrow<B>,250B:?Sized,251{252ifcfg!(debug_assertions) {253func(Borrow::<B>::borrow(&self));254}255self256}257258/// Calls `.tap_borrow_mut()` only in debug builds, and is erased in release259/// builds.260#[inline(always)]261fntap_borrow_mut_dbg<B>(mutself, func:implFnOnce(&mutB)) ->Self262where263Self: BorrowMut<B>,264B:?Sized,265{266ifcfg!(debug_assertions) {267func(BorrowMut::<B>::borrow_mut(&mutself));268}269self270}271272/// Calls `.tap_ref()` only in debug builds, and is erased in release273/// builds.274#[inline(always)]275fntap_ref_dbg<R>(self, func:implFnOnce(&R)) ->Self276where277Self: AsRef<R>,278R:?Sized,279{280ifcfg!(debug_assertions) {281func(AsRef::<R>::as_ref(&self));282}283self284}285286/// Calls `.tap_ref_mut()` only in debug builds, and is erased in release287/// builds.288#[inline(always)]289fntap_ref_mut_dbg<R>(mutself, func:implFnOnce(&mutR)) ->Self290where291Self: AsMut<R>,292R:?Sized,293{294ifcfg!(debug_assertions) {295func(AsMut::<R>::as_mut(&mutself));296}297self298}299300/// Calls `.tap_deref()` only in debug builds, and is erased in release301/// builds.302#[inline(always)]303fntap_deref_dbg<T>(self, func:implFnOnce(&T)) ->Self304where305Self: Deref<Target = T>,306T:?Sized,307{308ifcfg!(debug_assertions) {309func(Deref::deref(&self));310}311self312}313314/// Calls `.tap_deref_mut()` only in debug builds, and is erased in release315/// builds.316#[inline(always)]317fntap_deref_mut_dbg<T>(mutself, func:implFnOnce(&mutT)) ->Self318where319Self: DerefMut + Deref<Target = T>,320T:?Sized,321{322ifcfg!(debug_assertions) {323func(DerefMut::deref_mut(&mutself));324}325self326}327}328329impl<T> TapforTwhereT: Sized {}330331/** Optional tapping, conditional on the optional presence of a value.332333This trait is intended for use on types that express the concept of “optional334presence”, primarily the [`Option`] monad. It provides taps that inspect the335container to determine if the effect function should execute or not.336337> Note: This trait is a specialization of [`TapFallible`], and exists because338> the [`std::ops::Try`] trait is still unstable. When `Try` stabilizes, this339> trait can be removed, and `TapFallible` blanket-applied to all `Try`340> implementors.341342[`Option`]: https://doc.rust-lang.org/std/option/enum.Option.html343[`TapFallible`]: trait.TapFallible.html344[`std::ops::Try`]: https://doc.rust-lang.org/std/ops/trait.Try.html345**/346pub traitTapOptional347where348Self: Sized,349{350/// The interior type that the container may or may not carry.351typeVal:?Sized;352353/// Immutabily accesses an interior value only when it is present.354///355/// This function is identical to [`Tap::tap`], except that it is required356/// to check the implementing container for value presence before running.357/// Implementors must not run the effect function if the container is marked358/// as being empty.359///360/// [`Tap::tap`]: trait.Tap.html#method.tap361fntap_some(self, func:implFnOnce(&Self::Val)) ->Self;362363/// Mutably accesses an interor value only when it is present.364///365/// This function is identical to [`Tap::tap_mut`], except that it is366/// required to check the implementing container for value presence before367/// running. Implementors must not run the effect function if the container368/// is marked as being empty.369///370/// [`Tap::tap_mut`]: trait.Tap.html#method.tap_mut371fntap_some_mut(self, func:implFnOnce(&mutSelf::Val)) ->Self;372373/// Runs an effect function when the container is empty.374///375/// This function is identical to [`Tap::tap`], except that it is required376/// to check the implementing container for value absence before running.377/// Implementors must not run the effect function if the container is marked378/// as being non-empty.379///380/// [`Tap::tap`]: trait.Tap.html#method.tap381fntap_none(self, func:implFnOnce()) ->Self;382383/// Calls `.tap_some()` only in debug builds, and is erased in release384/// builds.385#[inline(always)]386fntap_some_dbg(self, func:implFnOnce(&Self::Val)) ->Self{387ifcfg!(debug_assertions) {388self.tap_some(func)389}else{390self391}392}393394/// Calls `.tap_some_mut()` only in debug builds, and is erased in release395/// builds.396#[inline(always)]397fntap_some_mut_dbg(self, func:implFnOnce(&mutSelf::Val)) ->Self{398ifcfg!(debug_assertions) {399self.tap_some_mut(func)400}else{401self402}403}404405/// Calls `.tap_none()` only in debug builds, and is erased in release406/// builds.407#[inline(always)]408fntap_none_dbg(self, func:implFnOnce()) ->Self{409ifcfg!(debug_assertions) {410self.tap_none(func)411}else{412self413}414}415}416417impl<T> TapOptionalforOption<T> {418typeVal = T;419420#[inline(always)]421fntap_some(self, func:implFnOnce(&T)) ->Self{422if letSome(refval) =self{423func(val);424}425self426}427428#[inline(always)]429fntap_some_mut(mutself, func:implFnOnce(&mutT)) ->Self{430if letSome(ref mutval) =self{431func(val);432}433self434}435436#[inline(always)]437fntap_none(self, func:implFnOnce()) ->Self{438ifself.is_none() {439func();440}441self442}443}444445/** Fallible tapping, conditional on the optional success of an expression.446447This trait is intended for use on types that express the concept of “fallible448presence”, primarily the [`Result`] monad. It provides taps that inspect the449container to determine if the effect function should execute or not.450451> Note: This trait would ideally be implemented as a blanket over all452> [`std::ops::Try`] implementors. When `Try` stabilizes, this crate can be453> updated to do so.454455[`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html456[`std::ops::Try`]: https://doc.rust-lang.org/std/ops/trait.Try.html457**/458pub traitTapFallible459where460Self: Sized,461{462/// The interior type used to indicate a successful construction.463typeOk:?Sized;464465/// The interior type used to indicate a failed construction.466typeErr:?Sized;467468/// Immutably accesses an interior success value.469///470/// This function is identical to [`Tap::tap`], except that it is required471/// to check the implementing container for value success before running.472/// Implementors must not run the effect function if the container is marked473/// as being a failure.474///475/// [`Tap::tap`]: trait.Tap.html#method.tap476fntap_ok(self, func:implFnOnce(&Self::Ok)) ->Self;477478/// Mutably accesses an interior success value.479///480/// This function is identical to [`Tap::tap_mut`], except that it is481/// required to check the implementing container for value success before482/// running. Implementors must not run the effect function if the container483/// is marked as being a failure.484///485/// [`Tap::tap_mut`]: trait.Tap.html#method.tap_mut486fntap_ok_mut(self, func:implFnOnce(&mutSelf::Ok)) ->Self;487488/// Immutably accesses an interior failure value.489///490/// This function is identical to [`Tap::tap`], except that it is required491/// to check the implementing container for value failure before running.492/// Implementors must not run the effect function if the container is marked493/// as being a success.494///495/// [`Tap::tap`]: trait.Tap.html#method.tap496fntap_err(self, func:implFnOnce(&Self::Err)) ->Self;497498/// Mutably accesses an interior failure value.499///500/// This function is identical to [`Tap::tap_mut`], except that it is501/// required to check the implementing container for value failure before502/// running. Implementors must not run the effect function if the container503/// is marked as being a success.504///505/// [`Tap::tap_mut`]: trait.Tap.html#method.tap_mut506fntap_err_mut(self, func:implFnOnce(&mutSelf::Err)) ->Self;507508/// Calls `.tap_ok()` only in debug builds, and is erased in release builds.509#[inline(always)]510fntap_ok_dbg(self, func:implFnOnce(&Self::Ok)) ->Self{511ifcfg!(debug_assertions) {512self.tap_ok(func)513}else{514self515}516}517518/// Calls `.tap_ok_mut()` only in debug builds, and is erased in release519/// builds.520#[inline(always)]521fntap_ok_mut_dbg(self, func:implFnOnce(&mutSelf::Ok)) ->Self{522ifcfg!(debug_assertions) {523self.tap_ok_mut(func)524}else{525self526}527}528529/// Calls `.tap_err()` only in debug builds, and is erased in release530/// builds.531#[inline(always)]532fntap_err_dbg(self, func:implFnOnce(&Self::Err)) ->Self{533ifcfg!(debug_assertions) {534self.tap_err(func)535}else{536self537}538}539540/// Calls `.tap_err_mut()` only in debug builds, and is erased in release541/// builds.542#[inline(always)]543fntap_err_mut_dbg(self, func:implFnOnce(&mutSelf::Err)) ->Self{544ifcfg!(debug_assertions) {545self.tap_err_mut(func)546}else{547self548}549}550}551552impl<T, E> TapFallibleforResult<T, E> {553typeOk= T;554typeErr= E;555556#[inline(always)]557fntap_ok(self, func:implFnOnce(&T)) ->Self{558if letOk(refval) =self{559func(val);560}561self562}563564#[inline(always)]565fntap_ok_mut(mutself, func:implFnOnce(&mutT)) ->Self{566if letOk(ref mutval) =self{567func(val);568}569self570}571572#[inline(always)]573fntap_err(self, func:implFnOnce(&E)) ->Self{574if letErr(refval) =self{575func(val);576}577self578}579580#[inline(always)]581fntap_err_mut(mutself, func:implFnOnce(&mutE)) ->Self{582if letErr(ref mutval) =self{583func(val);584}585self586}587}

[8]ページ先頭

©2009-2025 Movatter.jp