pub struct Documents { /* private fields */ }Expand description
Every open document + which one is active. Always holds AT LEAST ONE
document: closing the last tab leaves a fresh untitled one in its place, so
Documents::engine_mut is infallible and the shell never has to render a
“no document” state that would be an empty viewport with extra steps.
Implementations§
Source§impl Documents
impl Documents
Sourcepub fn tabs_holding(&self, key: &str, except: u64) -> Vec<(u64, String)>
pub fn tabs_holding(&self, key: &str, except: u64) -> Vec<(u64, String)>
The open tabs other than except whose documents place a copy of
key at any depth: (tab id, title). A part tab saved under a new
name asks whether these should follow it.
Sourcepub fn retarget_copies(
&mut self,
id: u64,
old: &str,
new_key: &str,
text: &str,
) -> Result<usize, String>
pub fn retarget_copies( &mut self, id: u64, old: &str, new_key: &str, text: &str, ) -> Result<usize, String>
Point every copy of old in tab id at the document text saved as
new_key: one undoable edit, after which the tab is unsaved and its
next Save writes the new reference. The number of copies moved.
Source§impl Documents
impl Documents
Sourcepub fn owned_changes(&self) -> OwnedChanges
pub fn owned_changes(&self) -> OwnedChanges
What the active tab’s next Save writes besides itself.
Sourcepub fn synced_signatures(&self) -> HashMap<String, String>
pub fn synced_signatures(&self) -> HashMap<String, String>
Each top-level parts-library entry’s sourceSignature as of the
active tab’s last Open/Save: the file version it last synced with
(panels::update_components judges “outdated” against it). An entry
added since (an insert) is synced with the version it was first seen
at, which is the insert’s. Cached per baseline.
Sourcepub fn owned_modified_keys(&self) -> Vec<String>
pub fn owned_modified_keys(&self) -> Vec<String>
The source documents the active tab’s next Save writes ([key]).
Sourcepub fn owned_modified_keys_of(&self, id: u64) -> Vec<String>
pub fn owned_modified_keys_of(&self, id: u64) -> Vec<String>
The source documents the next Save of tab id writes, cached per edit
(the Work part bar asks every frame; the diff serializes the assembly).
Sourcepub fn plan_owned_save(
&self,
store: &dyn ModelStore,
saving_as: &str,
) -> OwnedSavePlan
pub fn plan_owned_save( &self, store: &dyn ModelStore, saving_as: &str, ) -> OwnedSavePlan
Save step one: what the active tab’s Save would write besides itself,
and the decisions it needs. saving_as is the name the tab is about
to be written under.
Sourcepub fn save_part_as(
&mut self,
index: usize,
store: &dyn ModelStore,
component_path: &str,
key: &str,
overwrite: bool,
) -> Result<(), String>
pub fn save_part_as( &mut self, index: usize, store: &dyn ModelStore, component_path: &str, key: &str, overwrite: bool, ) -> Result<(), String>
“Save part as…”: the file-less part placed at component_path in the
tab at index (it lives only inside that assembly) gets the new part
file key now, under the name the user chose, and every file-less copy
of the same part, at any depth, is linked to it — what the Save’s own
promotion does under the library entry’s name. Nothing stays embedded.
The assembly is then unsaved: its next Save keeps the reference. A part
that has a file of its own is refused; a name already taken only with
overwrite (the dialog asks first).
Sourcepub fn execute_owned_save(
&mut self,
store: &dyn ModelStore,
plan: OwnedSavePlan,
) -> (OwnedSaveReport, Vec<CheckoutRequest>)
pub fn execute_owned_save( &mut self, store: &dyn ModelStore, plan: OwnedSavePlan, ) -> (OwnedSaveReport, Vec<CheckoutRequest>)
Save step two, BEFORE the active tab itself is written: carry out
plan (with the user’s answers), deepest first. The assembly’s
own document takes the signatures (and any new file names) of what was
written. PLM checkouts come back to the caller, which writes each one
when its checkout lands.
Sourcepub fn mark_unsaved_copies(&mut self, doc_id: u64, key: &str, why: &str) -> bool
pub fn mark_unsaved_copies(&mut self, doc_id: u64, key: &str, why: &str) -> bool
A PLM checkout the Save asked for failed after the assembly was written:
mark key’s copies in the tab doc_id as holding a change not saved to
it, so the tab reads unsaved, the next Save asks again and no refresh
replaces the copy. true when the mark is new: the assembly as stored
was written without it, so it must be saved again.
Sourcepub fn mark_failed_copies(
&mut self,
store: &dyn ModelStore,
key: &str,
) -> Vec<u64>
pub fn mark_failed_copies( &mut self, store: &dyn ModelStore, key: &str, ) -> Vec<u64>
The write of the stored document key failed after the Save that made
it returned (a write-behind store: the server down, a refusal). Every
open document holding a copy of it marks that copy unsaved, as a
failed checkout does, and the mark goes into its stored document too:
the copy was stamped as written, so without the mark the next Save
would skip it and the next open would refresh it away. Returns the
tabs marked.
Sourcepub fn write_unsaved_marks(
&mut self,
store: &dyn ModelStore,
doc_id: u64,
was_clean: bool,
) -> Result<(), String>
pub fn write_unsaved_marks( &mut self, store: &dyn ModelStore, doc_id: u64, was_clean: bool, ) -> Result<(), String>
A mark Self::mark_unsaved_copies added after the assembly doc_id
was written: write its stored document again with the tab’s marks and
nothing else of the tab, so the stored assembly that holds the change
also says it is not saved to its item, and no open refreshes it away.
was_clean: the tab held nothing unsaved before the mark, so it is
clean again once written.
Sourcepub fn retarget_revised_copies(
&mut self,
doc_id: u64,
old_key: &str,
new_key: &str,
text: &str,
) -> Result<(), String>
pub fn retarget_revised_copies( &mut self, doc_id: u64, old_key: &str, new_key: &str, text: &str, ) -> Result<(), String>
A new revision the Save made holds the change of old_key’s copies as
new_key (text): every copy in the tab doc_id now names it, and the
mark goes. The documents that hold a copy changed with it (they name
another revision), so the caller saves the tab again.
Sourcepub fn clear_unsaved_copies(&mut self, doc_id: u64, key: &str) -> bool
pub fn clear_unsaved_copies(&mut self, doc_id: u64, key: &str) -> bool
A PLM checkout the Save asked for landed and key was written: drop
its mark in the tab doc_id. true when there was one: the assembly
as stored still carries it, so it must be saved again.
Sourcepub fn settle_tab(&mut self, key: &str, text: &str)
pub fn settle_tab(&mut self, key: &str, text: &str)
The open tab (other than the active one) of key, after text was
written to it: clean when it shows text, else reloaded from it.
Source§impl Documents
impl Documents
Sourcepub fn occurrence_part(
&self,
component_path: &str,
) -> Result<(String, Option<String>), String>
pub fn occurrence_part( &self, component_path: &str, ) -> Result<(String, Option<String>), String>
The part an occurrence places, at any depth (ACOMP1:ACOMP2), in the
active tab: its part-library name and its source file (None or empty:
a part with no file of its own).
Sourcepub fn begin_work_part(&mut self, component_path: &str) -> Result<(), String>
pub fn begin_work_part(&mut self, component_path: &str) -> Result<(), String>
Make component_path the Work part, in place (no tab switch).
pub fn begin_work_part_as( &mut self, component_path: &str, mode: WorkPartMode, ) -> Result<(), String>
Sourcepub fn work_part_in_place(&self) -> bool
pub fn work_part_in_place(&self) -> bool
Whether a Work part is being edited in place in the active tab.
Sourcepub fn work_part_assembly(&self) -> Option<&EngineState>
pub fn work_part_assembly(&self) -> Option<&EngineState>
The assembly engine of the active Work part session (the tab’s own engine while in place).
pub fn work_part_assembly_mut(&mut self) -> Option<&mut EngineState>
Sourcepub fn work_part_path(&self) -> Option<&str>
pub fn work_part_path(&self) -> Option<&str>
The component path being edited, if any.
Sourcepub fn work_part_settling(&self) -> bool
pub fn work_part_settling(&self) -> bool
Whether the Work part session still owes the assembly an update: a settled part state not pushed yet, an assembly run in flight, or a context not rebuilt from the assembly’s latest run.
Sourcepub fn work_part_modified_sources(&self) -> Vec<String>
pub fn work_part_modified_sources(&self) -> Vec<String>
The source files the ACTIVE tab’s next Save writes besides itself:
every owned document its edits changed (super::owned_save).
Sourcepub fn flush_work_part(&mut self)
pub fn flush_work_part(&mut self)
Push the Work part’s latest state now, even while the assembly is still running (Save and the document readback call this). A refusal is kept for the bar; the part edits stay in the Work part.
Sourcepub fn work_part_up_to(&mut self, depth: usize) -> Result<(), String>
pub fn work_part_up_to(&mut self, depth: usize) -> Result<(), String>
Go up the Work part’s path to depth: 0 is the assembly itself, k
the occurrence of its first k components (a sub-assembly above the
part). The part’s edits are pushed first, and the sub-assembly becomes
the Work part once that update has landed, so it is placed where the
solved assembly puts it (Self::begin_next_work_part).
Sourcepub fn work_part_up(&mut self) -> Result<(), String>
pub fn work_part_up(&mut self) -> Result<(), String>
One level up: the sub-assembly holding the Work part, or the assembly.
pub fn return_to_assembly(&mut self) -> Result<(), String>
Sourcepub fn work_part_state(&self) -> Value
pub fn work_part_state(&self) -> Value
The Work part session as automation state (null when inactive).
pub fn show_work_part_bar(&mut self, ui: &mut Ui, store: &dyn ModelStore)
Source§impl Documents
impl Documents
Sourcepub fn new(new_engine: EngineFactory) -> Self
pub fn new(new_engine: EngineFactory) -> Self
A session holding one fresh document built by new_engine.
Sourcepub fn wrap_engine_factory(
&mut self,
wrap: impl Fn(EngineState) -> EngineState + 'static,
)
pub fn wrap_engine_factory( &mut self, wrap: impl Fn(EngineState) -> EngineState + 'static, )
A fresh engine for a document about to be opened — the caller loads into
it and hands the result to Self::open_document.
Seeded with the WHOLE of the session’s settings, workbench included, so
a new tab continues what you were doing. The load that follows overrides
the workbench if the document names one (see the module header).
Build every later tab’s engine through wrap as well: the app’s live
PLM reconnect puts the new store’s settings over the factory’s.
pub fn spawn_engine(&self) -> EngineState
Sourcepub fn engine(&self) -> &EngineState
pub fn engine(&self) -> &EngineState
The engine the user is editing: the active tab’s, or — while a Work
part is edited in place in that tab — the hosted part’s
(work_part). Save, the dirty dot and the tab identity stay the
tab’s own (Self::active, Self::tab_engine).
pub fn engine_mut(&mut self) -> &mut EngineState
Sourcepub fn tab_engine(&self) -> &EngineState
pub fn tab_engine(&self) -> &EngineState
The active TAB’s own engine — the document Save writes. The same as
Self::engine except while a Work part is edited in place, when this
is the assembly.
pub fn tab_engine_mut(&mut self) -> &mut EngineState
Sourcepub fn view_id(&self) -> u64
pub fn view_id(&self) -> u64
The identity of what the panels and viewport are drawing: the hosted Work part’s document while one is edited in place, else the active tab’s. The shell resets its document-scoped state when this changes.
pub fn active(&self) -> &Document
pub fn active_mut(&mut self) -> &mut Document
Sourcepub fn view(&self) -> &Document
pub fn view(&self) -> &Document
The document being DRAWN and edited: the hosted Work part while one is
edited in place, else the active tab (Self::active stays the tab,
for its name, dirty state and Save).
pub fn view_mut(&mut self) -> &mut Document
pub fn active_index(&self) -> usize
Sourcepub fn index_of_id(&self, id: u64) -> Option<usize>
pub fn index_of_id(&self, id: u64) -> Option<usize>
The tab holding the document whose process-unique id is id.
Sourcepub fn engine_of_handle_mut(&mut self, handle: &str) -> Option<&mut EngineState>
pub fn engine_of_handle_mut(&mut self, handle: &str) -> Option<&mut EngineState>
The engine of the document whose public handle is handle (any tab).
Sourcepub fn index_of_handle(&self, handle: &str) -> Option<usize>
pub fn index_of_handle(&self, handle: &str) -> Option<usize>
The tab whose public handle is handle.
Sourcepub fn active_id(&self) -> u64
pub fn active_id(&self) -> u64
The ACTIVE document’s handle — the shell compares it frame to frame to notice a switch from ANY source (a tab click, a close, New, Open, Open Part, a crash-recovery restore) with one check instead of a hook per site.
pub fn len(&self) -> usize
pub fn get(&self, index: usize) -> Option<&Document>
pub fn get_mut(&mut self, index: usize) -> Option<&mut Document>
pub fn iter(&self) -> Iter<'_, Document> ⓘ
pub fn iter_mut(&mut self) -> IterMut<'_, Document> ⓘ
Sourcepub fn pump_all(&mut self) -> bool
pub fn pump_all(&mut self) -> bool
Land every open document’s finished runs; true while any of them still
has work in flight, so the frame loop keeps pumping.
EVERY open document is pumped, not just the active one: a run belongs to
the engine that submitted it (each document owns its own runner), so a
run still in flight when the user switches tabs must land in ITS
document rather than be dropped or, worse, applied to whatever is on
screen. An idle document’s pump is a couple of empty try_recvs.
The kernel’s parts library is one store for every tab, and a pump can
SUBMIT a run as well as land one: EngineState::pump re-runs after its
runner refused a run for a library it no longer holds, after a ports
edit moved a point, and when a mesh reconstruction lands (its STEP is
imported, which writes the store into the document and runs). A submit hands the runner whatever library is
in the store, and a run that lands mirrors the store it ran with into
its document’s own partsLibrary block. So a tab in the BACKGROUND that
may do either — a run in flight, or a point move waiting — is pumped with
ITS library installed, and the active document’s is put back right after.
(A STEP probe’s reply only stashes what it found, and landing a run
submits nothing, so those need no more than run_pending.)
Pumped with the active one’s, it resolved its components against another
document’s parts, and the run that landed wrote that into its own file.
An idle background tab submits and lands nothing, so it costs nothing.
Sourcepub fn set_canonicalizer(&mut self, canon: Canonicalizer)
pub fn set_canonicalizer(&mut self, canon: Canonicalizer)
Compare identities the way the store does (the shell installs it).
Sourcepub fn index_of_source(&self, key: &str) -> Option<usize>
pub fn index_of_source(&self, key: &str) -> Option<usize>
The tab holding the document key names, in the store’s spelling.
Sourcepub fn index_of(&self, name: &str) -> Option<usize>
pub fn index_of(&self, name: &str) -> Option<usize>
The tab holding the document stored under name, if any.
Sourcepub fn focus_named(&mut self, name: &str) -> bool
pub fn focus_named(&mut self, name: &str) -> bool
Activate the tab already holding name; false when it is not open.
The “focus the existing tab” half of open-or-focus.
Sourcepub fn open_document(&mut self, doc: Document) -> usize
pub fn open_document(&mut self, doc: Document) -> usize
Add doc as a new tab and make it active.
Sourcepub fn open_document_behind(&mut self, doc: Document) -> usize
pub fn open_document_behind(&mut self, doc: Document) -> usize
Add a tab WITHOUT activating it: the visible document, its panels and
camera stay as they are (an agent’s cad.documents.create). Its seed
run lands as a background tab’s does (pump_all).
Sourcepub fn activate(&mut self, index: usize)
pub fn activate(&mut self, index: usize)
Make tab index active, carrying the session’s display settings over to
it. Out-of-range indices are ignored (a stale click never panics).
Sourcepub fn close(&mut self, index: usize)
pub fn close(&mut self, index: usize)
Close tab index. Closing the LAST document leaves a fresh untitled one
(the always-one-document invariant); closing a tab before the active one
keeps the same document active at its new index.
The caller is responsible for the unsaved-changes prompt — this is the
mechanical close (panels::file owns the confirmation).
Sourcepub fn mark_write_failed(&mut self, store: &dyn ModelStore, name: &str) -> bool
pub fn mark_write_failed(&mut self, store: &dyn ModelStore, name: &str) -> bool
Refresh every tab’s dirty dot (see Document::refresh_dirty_marker).
The write of document name failed after its Save returned: the tabs
showing it (any spelling of the same identity) read unsaved again.
Whether one did.
pub fn refresh_dirty_markers(&mut self)
Auto Trait Implementations§
impl !Freeze for Documents
impl !RefUnwindSafe for Documents
impl !Send for Documents
impl !Sync for Documents
impl !UnwindSafe for Documents
impl Unpin for Documents
impl UnsafeUnpin for Documents
Blanket Implementations§
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§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>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§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>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§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.Source§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.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§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 moreSource§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§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 moreSource§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 moreSource§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
Source§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
Source§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.Source§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.Source§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.Source§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§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 moreSource§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 moreSource§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 moreSource§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 moreSource§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 moreSource§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 moreSource§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.Source§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.Source§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.Source§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.Source§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.Source§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.Source§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.