Skip to main content

AppHandle

Struct AppHandle 

Source
pub struct AppHandle { /* private fields */ }

Implementations§

Source§

impl AppHandle

Source

pub async fn start() -> Result<Self>

Source

pub fn peek_mdns_enabled(master_key: Option<&[u8; 32]>) -> Result<bool>

huddle 0.7.8: peek the persisted mdns_enabled setting without starting the full AppHandle. Called by main.rs before start_with_options so the initial NetworkMode reflects the user’s saved preference (the CLI --mode flag, when present, still wins — main.rs only calls this if --mode is absent). Returns true if the key is missing (default ON, preserving pre-0.7.8 behavior).

Source

pub async fn start_with_options( mode: NetworkMode, port: u16, master_key: Option<&[u8; 32]>, relays: Vec<Multiaddr>, ) -> Result<Self>

Source

pub async fn start_with_db(db: Db) -> Result<Self>

Source

pub async fn start_with_db_and_options( db: Db, mode: NetworkMode, port: u16, session_persist_key: [u8; 32], relays: Vec<Multiaddr>, ) -> Result<Self>

Source

pub fn mode(&self) -> NetworkMode

Source

pub fn subscribe(&self) -> Receiver<AppEvent>

Source

pub fn fingerprint(&self) -> &str

Source

pub fn peer_id(&self) -> PeerId

Source

pub fn sign_invite(&self, invite: InviteLink) -> Result<InviteLink>

huddle 0.7.11: bind an invite link to our Ed25519 identity by signing it. The receiver re-derives the fingerprint from the embedded pubkey and rejects the invite if any signed field (host_multiaddr, fingerprint, room id/name/encrypted/salt/ creator_fp/owner_list, signed_at_ms) was tampered with.

Source

pub fn discovered_rooms(&self) -> Vec<DiscoveredRoom>

Source

pub fn dm_partner_fingerprint(&self, room_id: &str) -> Option<String>

huddle 0.7: returns the fingerprint of the other party in a 1-1 DM. None for rooms that are Group, missing, or somehow have a non-2-member state. Used by the DM-pane header to render the partner’s username + HD-ID.

Source

pub fn active_room_ids(&self) -> Vec<String>

Source

pub fn active_room_info(&self, room_id: &str) -> Option<StoredRoom>

Source

pub fn room_members(&self, room_id: &str) -> Vec<String>

Source

pub fn room_messages( &self, room_id: &str, limit: i64, ) -> Result<Vec<StoredRoomMessage>>

Source

pub fn search_room_messages( &self, room_id: &str, query: &str, limit: i64, ) -> Result<Vec<StoredRoomMessage>>

Source

pub async fn start_room( &self, name: &str, encrypted: bool, passphrase: Option<&str>, kind: RoomKind, ) -> Result<String>

Create a new room. Returns its room_id.

huddle 0.7: kind is now required. RoomKind::Group (the default) preserves pre-0.7 behavior. RoomKind::Direct is reserved for callers that have already computed a deterministic DM room_id via canonical_dm_room_id — most clients should call start_direct instead, which handles idempotency, kind, and naming.

Source

pub async fn start_direct(&self, partner_fingerprint: &str) -> Result<String>

huddle 0.7.1: start (or open) a 1-1 DM with partner_fingerprint.

Idempotent across peers and reopens:

  1. Refuses to DM yourself.
  2. Computes room_id = canonical_dm_room_id(our_fp, partner_fp). Both peers, regardless of who clicks first, derive identical IDs.
  3. If a DM room already exists locally (active or stored), returns its id — no new room, no second announcement.
  4. Otherwise creates a RoomKind::Direct, end-to-end encrypted room. The key is derived from Ed25519→X25519 ECDH between the two parties’ identity keys (see crypto::dm::derive_dm_key). No shared passphrase, no central key agreement — both peers independently derive the same 32-byte room key from their own seed + the other’s pubkey.
  5. If we don’t yet know the partner’s Ed25519 pubkey, the room is still created encrypted; the key is derived lazily once MemberAnnounce arrives with the partner’s pubkey, after which we send our wrapped Megolm session key in a follow-up announce.
  6. Subscribes to the room topic and announces on the global topic. The announcement is visibility-filtered at honest 0.7+ peers, so only the partner sees it in their discovered_rooms().
Source

pub async fn join_room( &self, room_id: &str, passphrase: Option<&str>, ) -> Result<()>

Join an existing room. The room may come from a live announcement (preferred), our restorable set, or the DB directly — whichever has the freshest copy. For encrypted rooms passphrase is required.

Source

pub async fn leave_room(&self, room_id: &str) -> Result<bool>

Leave a room. Returns true when the MemberLeave notice was handed to the network layer, false when it couldn’t be encoded (peers then only notice via the discovered-room TTL). The local leave always succeeds regardless.

Source

pub async fn send_room_message(&self, room_id: &str, body: &str) -> Result<()>

Source

pub async fn shutdown(&self)

Source

pub async fn dial_by_id_or_username(&self, input: &str) -> Result<()>

Dial a peer by a user-entered address. Accepts:

  • 1.2.3.4:9000
  • [fe80::1]:9000
  • /ip4/.../tcp/...[/p2p/<peer>] (raw multiaddr) huddle 0.5.1: resolve an HD- ID or username back to a dialable multiaddr and dial it.

input is matched against, in order:

  1. an HD-XXXX-... prefixed string → strip prefix + lowercase to canonical fingerprint;
  2. a raw 24-char hex run (with or without dashes) → group into 4-char blocks and lowercase;
  3. otherwise → treat as a username and look up peer_profiles.

Resolution to an address: scan discovered_rooms for a room whose creator_fingerprint matches; take the first host_addrs entry. Falls back to the known_peers table for users we’ve dialed before. Both paths require we’ve seen the peer on our gossipsub mesh or dialed them before — bare-ID dialing on a cold mesh is fundamentally impossible without a routing layer huddle deliberately doesn’t run (DHT, central directory). For cross-internet first contact, paste an invite link instead.

Source

pub async fn dial(&self, input: &str) -> Result<()>

Source

pub fn nat_reachable_addrs(&self) -> Vec<String>

Phase D follow-up: snapshot of the NAT reachability state. Returns the addresses AutoNAT has confirmed as externally reachable in this session. The lobby renders an emoji badge from this — non-empty ⇒ ‘🌐 reachable’, empty ⇒ ‘🏠 LAN only’.

Source

pub fn dialable_addrs(&self) -> Vec<String>

Phase D follow-up: addresses suitable for putting on the wire so other peers can dial us. Union of:

  • AutoNAT-confirmed external addresses (direct internet)
  • active /p2p-circuit reservations on configured relays Capped at 4 entries to keep room announcements small. Relay-circuit addresses are listed first (they’re more likely to work for NAT’d peers).
Source

pub async fn dial_invite(&self, address: &str, claimed_fp: &str) -> Result<()>

Phase C follow-up: dial a peer whose multiaddr came from an invite link claiming claimed_fp. Behaves identically to dial, but additionally stashes (canonical_addr → claimed_fp) in pending_invite_dials so the PeerIdentified handler can assert the cryptographic fp matches the human-display one in the invite. Mismatch ⇒ disconnect + InviteFingerprintMismatch event.

libp2p’s /p2p/<peer-id> segment already enforces this at the transport level (and our invite generator always includes it), so this is defense in depth — but it makes the assert explicit rather than relying on a structural side effect.

Source

pub fn known_peers(&self) -> Vec<KnownPeerStatus>

Source

pub async fn forget_peer(&self, address: &str) -> Result<()>

Source

pub async fn redial(&self, address: &str) -> Result<()>

Re-dial a stored address — used by the lobby’s “reconnect” action.

Source

pub async fn accept_inbound(&self, peer_id: PeerId, address: &str)

Phase A: user pressed Accept on the inbound-dial modal. Promotes the peer to the gossipsub mesh. Does NOT mark them trusted — that’s trust_inbound, the explicit “remember and bypass next time” path.

Source

pub async fn reject_inbound( &self, peer_id: PeerId, fingerprint: &str, ) -> Result<()>

Phase A: user pressed Reject on the inbound-dial modal. Disconnects the peer, adds them to the persistent blocklist, and ensures every subsequent connection attempt from this fingerprint is auto- dropped without re-prompting.

Source

pub async fn trust_inbound( &self, peer_id: PeerId, fingerprint: &str, address: &str, ) -> Result<()>

Phase A: user pressed Trust+Accept — accept the connection AND remember the peer so subsequent connections bypass the modal.

Source

pub fn list_pending_friend_requests(&self) -> Vec<PendingFriendRequest>

Snapshot of every inbound dial we’ve spilled to disk but haven’t yet accepted or rejected. The People pane renders this as its own section (“Pending requests (N)”).

Source

pub fn spill_pending_friend_request( &self, peer_id: PeerId, fingerprint: &str, address: &str, ) -> Result<()>

Persist an inbound request that the user didn’t act on within the modal window. Called from the TUI’s idle-timeout sweep; the live libp2p connection is also closed by the same path (the request is effectively rejected for now — accept later from People pane will re-dial the stored address).

Source

pub async fn accept_pending_friend_request( &self, fingerprint: &str, ) -> Result<()>

User pressed Accept on a row in the Pending requests list. The original libp2p connection is long gone (we closed it on timeout); re-dial the stored address and mark the peer trusted so the post-Identify handler short-circuits the modal. The row is removed regardless of dial success — a failed dial is still a positive intent we don’t want to keep re-prompting on.

Source

pub fn reject_pending_friend_request(&self, fingerprint: &str) -> Result<()>

User pressed Reject on a row in the Pending requests list. Mirrors reject_inbound semantics: delete the pending row(s) AND block the fingerprint so any future dial from this peer is auto-dropped without re-prompting.

Source

pub async fn disconnect_peer(&self, peer_id: PeerId)

huddle 0.7.7: close a live libp2p connection without blocking the peer. Used by the TUI’s 15s InboundDial timeout — we need to drop the dangling socket, but blocking the peer would contradict “save the request for 3 days, let the user decide later.” reject_inbound is the right call when the user explicitly clicks Reject.

Source

pub async fn send_file(&self, room_id: &str, path: &Path) -> Result<String>

Send a local file to a room. Reads the file, optionally encrypts it for encrypted rooms, chunks it, broadcasts a FileOffer then each FileChunk. Returns the file_id once all chunks are queued.

Source

pub async fn save_to_downloads( &self, room_id: &str, file_id: &str, ) -> Result<PathBuf>

Save a completed/ready attachment to the user’s Downloads folder. Decrypts encrypted attachments on the way out.

Source

pub async fn cancel_transfer(&self, room_id: &str, file_id: &str) -> Result<()>

Drop any in-flight chunks and remove the attachment row.

Source

pub fn open_saved(&self, room_id: &str, file_id: &str) -> Result<()>

Launch the system’s default opener on a saved file.

Source

pub fn list_room_attachments( &self, room_id: &str, ) -> Result<Vec<StoredAttachment>>

Source

pub fn set_member_verified( &self, room_id: &str, fingerprint: &str, verified: bool, ) -> Result<()>

Mark a peer’s fingerprint as verified in the given room. Used by the ^V verification modal after the user has compared the fingerprint out-of-band.

Source

pub fn verified_fingerprints(&self, room_id: &str) -> Vec<String>

Source

pub fn is_owner(&self, room_id: &str, fingerprint: &str) -> bool

Phase B: is fingerprint an owner of room_id? Used by the TUI to gate ^K / ^G and the kick/grant member-picker actions.

Source

pub fn we_are_owner(&self, room_id: &str) -> bool

Source

pub fn room_owners(&self, room_id: &str) -> Vec<String>

Phase B: list current owner fingerprints for room_id — used to render an owner badge in the member panel.

Source

pub fn has_master_passphrase(&self) -> bool

huddle 0.7.6: true iff this session was started with a master passphrase. The TUI uses this to pick the Go Dark gate — passphrase if available (the natural strong secret the user already knows), else the typed DELETE EVERYTHING phrase since no-master-passphrase sessions have nothing else to compare against.

Source

pub fn verified_only_inbound(&self) -> bool

Phase E: global toggle — when true, inbound dials from unverified fingerprints are auto-rejected without prompting.

Source

pub fn set_verified_only_inbound(&self, on: bool) -> Result<()>

Source

pub fn mdns_enabled(&self) -> bool

huddle 0.7.8: persisted LAN-discovery toggle. When true, the next launch starts in NetworkMode::Mdns so the device joins LAN mDNS announcements. When false, the next launch starts in NetworkMode::Direct — invisible to LAN broadcast; only direct dial / invite link / configured relays can establish a peer. Default ON so existing users see no behavior change. Restart required to apply (libp2p’s Toggle<Mdns> flip would require a behaviour rebuild; not worth the complexity for a rarely-touched setting).

Source

pub fn set_mdns_enabled(&self, on: bool) -> Result<()>

Source

pub fn notifications_enabled(&self) -> bool

huddle 0.7.8: persisted desktop-notification opt-out. The notifier itself is a local-only osascript/notify-send process call — toggling this OFF skips the call entirely so nothing reaches the OS notification daemon. Default ON to preserve current behavior.

Source

pub fn set_notifications_enabled(&self, on: bool) -> Result<()>

Source

pub fn safety_code(&self) -> String

huddle 0.7.8: stable 12-hex Safety Code derived from our Ed25519 pubkey. Display-only; used as a quick visual fingerprint match in Profile / Account. SAS-via-emoji remains the actual verification primitive.

Source

pub fn room_verified_only(&self, room_id: &str) -> bool

Phase E: per-room verified-only-join. When true, the host (and every honest existing member) drops MemberAnnounce from joiners who aren’t globally SAS-verified, and the lowest-fp owner sends back a signed JoinRefused so the joiner sees an explanation.

Source

pub fn set_room_verified_only(&self, room_id: &str, on: bool) -> Result<()>

Source

pub fn onboarding_seen(&self) -> bool

Phase H: first-launch onboarding flag.

Source

pub fn mark_onboarding_seen(&self) -> Result<()>

Source

pub fn last_seen_onboarding_version(&self) -> Option<String>

huddle 0.6: version string of huddle the user last finished onboarding for. Compared against env!("CARGO_PKG_VERSION") at startup so a version bump re-fires the “what’s new” card.

Source

pub fn set_last_seen_onboarding_version(&self, version: &str) -> Result<()>

Source

pub fn update_check_enabled(&self) -> Option<bool>

huddle 0.6: opt-in flag for the crates.io update check. None ⇒ the user hasn’t been asked yet.

Source

pub fn set_update_check_enabled(&self, enabled: bool) -> Result<()>

Source

pub fn last_update_check_at(&self) -> i64

huddle 0.6: cache anchor for the once-per-24h crates.io poll. Returns 0 if nothing has been recorded yet.

Source

pub fn set_last_update_check_at(&self, ts: i64) -> Result<()>

Source

pub fn last_known_remote_version(&self) -> Option<String>

huddle 0.6: the most recent max_stable_version we saw on crates.io. Persisted so a re-launch within the 24h window can render the banner without re-fetching.

Source

pub fn set_last_known_remote_version(&self, v: &str) -> Result<()>

Source

pub async fn grant_owner( &self, room_id: &str, target_fingerprint: &str, ) -> Result<()>

Phase B: promote target_fingerprint to owner. Builds a signed OwnerGrant, broadcasts it, and applies it locally. Returns an error if we ourselves aren’t an owner — only owners can grant.

Source

pub async fn kick_member( &self, room_id: &str, target_fingerprint: &str, ) -> Result<String>

Phase B: kick target_fingerprint from room_id. Broadcasts a signed BanMember, records the ban locally, then immediately rotates the room key under a freshly-generated passphrase. Returns the new passphrase so the caller can show it to the owner for out-of-band sharing with remaining members.

The rotation is the cryptographic enforcement: a banned peer can still subscribe to the gossipsub topic and see the ciphertext, but they can’t unwrap the new session key without the new passphrase, so they can’t decrypt anything sent after the kick.

Source

pub fn generate_join_code(&self, room_id: &str) -> Result<String>

Phase F: generate an 8-char alphanumeric join code for room_id, good for 10 minutes. Stored in memory only on the issuing owner’s machine — a single use clears it. Caller is responsible for sharing the code OOB with the prospective joiner.

Owner-only. Errors if room_id isn’t active or we’re not an owner.

Source

pub async fn join_room_with_code(&self, room_id: &str, code: &str) -> Result<()>

Phase F: join room_id using a short-lived code instead of the passphrase. Generates an ephemeral X25519 keypair, broadcasts a signed CodeJoinRequest, and waits for the owner’s CodeJoinResponse. The receive arm builds an ActiveRoom flagged read-only (no passphrase = can’t share our outbound session key with others).

Source

pub async fn sas_start( &self, room_id: &str, target_fingerprint: &str, ) -> Result<String>

Phase G: start an SAS verification with target_fingerprint in room_id. Returns the tx_id so the caller can correlate subsequent events. The full flow is asynchronous — the partner must accept on their end, both compute the ECDH-derived SAS code, OOB-compare it, and each press Match.

Source

pub async fn sas_match(&self, tx_id: &str) -> Result<()>

Phase G: user pressed Match on the SAS code modal — broadcast our signed SasConfirm{matched: true}. If the partner has already matched, this completes verification on both sides.

Source

pub fn sas_cancel(&self, tx_id: &str)

Phase G: cancel an in-flight SAS — drop our local state. Doesn’t broadcast a “matched=false” notice in v1 (partner’s flow stays dangling; they can cancel their side too). Quiet teardown.

Source

pub fn display_name(&self) -> Option<String>

Source

pub fn set_display_name(&self, name: Option<&str>) -> Result<()>

Source

pub async fn set_username(&self, name: Option<&str>) -> Result<()>

huddle 0.5: set the local user’s self-declared username (or clear it with None) and broadcast a signed ProfileUpdate to every joined room. Receivers cache the latest per-fingerprint username in peer_profiles; unsigned envelopes are dropped at the receive arm so the username can’t be spoofed.

Source

pub fn lookup_username(&self, fingerprint: &str) -> Option<String>

huddle 0.5: cached username for a peer (any peer we’ve ever received a signed ProfileUpdate from), or None if unknown or the peer cleared their username. Callers render [anonymous] on None.

Source

pub fn lookup_member_display_name(&self, fingerprint: &str) -> Option<String>

Look up the display name we’ve seen for a peer. Forwards to lookup_username (the new signed-source-of-truth) so existing call sites get the authenticated value without churn.

Source

pub fn is_room_muted(&self, room_id: &str) -> bool

Source

pub fn list_room_bans(&self, room_id: &str) -> Vec<String>

Phase B: list the fingerprints currently banned from a room (newest first). Backs the ^B in-room view; intended for owners but the read itself is harmless and we let callers gate via we_are_owner if they want owner-only display.

Source

pub fn list_verified_peers(&self) -> Vec<String>

Phase A: list every globally-blocked peer (one fingerprint per row). Surfaced in the Settings modal alongside a clear-all action that calls unblock_peer in a loop. huddle 0.7: every globally SAS-verified peer. Surfaced in the People pane’s “Verified” sub-list.

Source

pub fn list_blocked_peers(&self) -> Vec<String>

Source

pub fn unblock_peer(&self, fingerprint: &str) -> Result<()>

Phase A: remove fingerprint from the persistent blocklist. The peer will no longer be auto-rejected on connection; they fall back to the regular inbound-dial accept/reject prompt.

Source

pub fn block_peer(&self, fingerprint: &str) -> Result<()>

huddle 0.7: add fingerprint to the persistent blocklist. Used by the People pane’s per-row “block” action. Subsequent inbound dials from this fingerprint are auto-rejected without prompting.

Source

pub fn is_room_read_only(&self, room_id: &str) -> bool

Phase F: rooms entered via a join code don’t have the passphrase in memory, so the joining peer can’t wrap their own outbound session key for newer members — they can read and send, they just can’t onboard others. The TUI renders a (read-only) badge in the room tab so the user understands.

Source

pub fn set_room_muted(&self, room_id: &str, muted: bool) -> Result<()>

Source

pub async fn broadcast_typing(&self, room_id: &str)

Broadcast a “I’m typing” pulse to the given room. Caller is responsible for debouncing (don’t fire more than every ~500ms).

Source

pub fn typers_in_room(&self, room_id: &str) -> Vec<String>

Returns the fingerprints of peers currently typing in room_id, pruning entries past their TTL.

Source

pub async fn rotate_room( &self, room_id: &str, new_passphrase: &str, ) -> Result<()>

Rotate this room’s outbound Megolm session under a fresh passphrase. Broadcasts RotateRoomKey (so other members know to expect a new passphrase) and a fresh MemberAnnounce with the new wrapped session key. Old inbound sessions stay in storage for decrypting historic messages.

Source

pub async fn accept_rotation( &self, room_id: &str, new_salt: &[u8], new_passphrase: &str, ) -> Result<()>

Used by the TUI when another member rotates a room we’re in. Derives the new key, updates our local state, and re-announces so the rotator can share their fresh outbound session with us.

Source

pub async fn go_dark(&self, master_passphrase: &str) -> Result<()>

huddle 0.5: irreversibly delete this account. Verifies the master passphrase, best-effort MemberLeaves every joined room (capped at 2 s so a single unresponsive transport can’t hang the wipe), shuts down the network, then deletes the database, keychain salt, log, and config files from config::data_dir(). Emits AppEvent::WentDark on success so the TUI can show a goodbye modal and exit.

In --no-master-passphrase mode (self.session_persist_key is all-zero), the passphrase check is skipped — the typed DELETE EVERYTHING confirmation in the TUI is the only gate.

Trait Implementations§

Source§

impl Clone for AppHandle

Source§

fn clone(&self) -> AppHandle

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

Auto Trait Implementations§

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

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

Source§

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

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

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

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

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

fn in_current_span(self) -> Instrumented<Self>

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

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

Source§

fn into(self) -> U

Calls U::from(self).

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

Source§

impl<T> IntoEither for T

Source§

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

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

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

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

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

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

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

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

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

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

impl<T, 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.
Source§

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

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

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

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

fn with_current_subscriber(self) -> WithDispatch<Self>

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