pub struct WalletStorageManager { /* private fields */ }Expand description
Multi-provider storage manager with hierarchical locking.
Wraps one or more WalletStorageProvider implementations. On first use
(or explicit make_available() call) partitions providers into
active / backups / conflicting_actives based on stored user preferences.
§Lock hierarchy
Four tokio::sync::Mutex<()> must be acquired in strict ascending order:
reader < writer < sync < storage_provider.
acquire_reader— read-only operationsacquire_writer— mutations (create/process/abort action, etc.)acquire_sync— sync loop operationsacquire_storage_provider— storage-provider-level operations
Implementations§
Source§impl WalletStorageManager
impl WalletStorageManager
Sourcepub fn new(
identity_key: String,
active: Option<Arc<dyn WalletStorageProvider>>,
backups: Vec<Arc<dyn WalletStorageProvider>>,
) -> Self
pub fn new( identity_key: String, active: Option<Arc<dyn WalletStorageProvider>>, backups: Vec<Arc<dyn WalletStorageProvider>>, ) -> Self
Create a new manager from an optional active provider and zero or more backups.
Providers are stored in order: active first (if Some), then backups.
No partitioning happens at construction — call make_available() to initialize.
Sourcepub fn get_user_identity_key(&self) -> &str
pub fn get_user_identity_key(&self) -> &str
Returns the wallet owner’s identity key.
Sourcepub fn is_available(&self) -> bool
pub fn is_available(&self) -> bool
Returns true after make_available() has successfully completed.
Sourcepub fn is_storage_provider(&self) -> bool
pub fn is_storage_provider(&self) -> bool
The manager itself is NOT a storage provider — always returns false.
Matches TS WalletStorageManager.isStorageProvider = false.
Sourcepub fn active(&self) -> Option<&Arc<dyn WalletStorageProvider>>
pub fn active(&self) -> Option<&Arc<dyn WalletStorageProvider>>
Returns the initial active provider (the first provider passed to the constructor).
This is a sync accessor that returns the provider as passed at construction,
before make_available() determines the actual active via partition logic.
Primarily used for backward-compatibility in sync contexts (Wallet::new, signer setup).
Sourcepub fn backups(&self) -> &[Arc<dyn WalletStorageProvider>]
pub fn backups(&self) -> &[Arc<dyn WalletStorageProvider>]
Returns the initial backup providers (the remaining providers from the constructor).
Sync accessor for backward-compatibility.
Sourcepub fn backup(&self) -> Option<&Arc<dyn WalletStorageProvider>>
pub fn backup(&self) -> Option<&Arc<dyn WalletStorageProvider>>
Returns the first backup provider if exactly one backup was provided.
Backward-compatibility alias for the old backup() method.
Sourcepub fn has_backup(&self) -> bool
pub fn has_backup(&self) -> bool
Returns true if at least one backup provider was provided.
Sourcepub async fn can_make_available(&self) -> bool
pub async fn can_make_available(&self) -> bool
Returns true if there is at least one provider registered.
Sourcepub async fn get_active_store(&self) -> WalletResult<String>
pub async fn get_active_store(&self) -> WalletResult<String>
Returns the active store’s settings.storage_identity_key.
Sourcepub async fn get_active_store_name(&self) -> WalletResult<String>
pub async fn get_active_store_name(&self) -> WalletResult<String>
Returns the active store’s settings.storage_name.
Sourcepub async fn get_active_settings(&self) -> WalletResult<Settings>
pub async fn get_active_settings(&self) -> WalletResult<Settings>
Returns a clone of the active store’s cached Settings.
Sourcepub async fn get_settings(&self) -> WalletResult<Settings>
pub async fn get_settings(&self) -> WalletResult<Settings>
Alias for get_active_settings() (TS parity name: getSettings).
Sourcepub async fn get_active_user(&self) -> WalletResult<User>
pub async fn get_active_user(&self) -> WalletResult<User>
Returns a clone of the active store’s cached User.
Sourcepub async fn get_backup_stores(&self) -> Vec<String>
pub async fn get_backup_stores(&self) -> Vec<String>
Returns storage_identity_key strings for all backup stores.
Sourcepub async fn get_conflicting_stores(&self) -> Vec<String>
pub async fn get_conflicting_stores(&self) -> Vec<String>
Returns storage_identity_key strings for all conflicting active stores.
Sourcepub async fn get_all_stores(&self) -> Vec<String>
pub async fn get_all_stores(&self) -> Vec<String>
Returns storage_identity_key strings for ALL stores.
Before make_available(), returns empty strings as placeholders so callers
can check the count without waiting for initialization.
Sourcepub async fn is_active_storage_provider(&self) -> WalletResult<bool>
pub async fn is_active_storage_provider(&self) -> WalletResult<bool>
Returns true if the active store’s is_storage_provider flag is set.
Sourcepub async fn is_active_enabled(&self) -> bool
pub async fn is_active_enabled(&self) -> bool
Returns true if active.settings.storage_identity_key == active.user.active_storage AND conflicting_active_indices is empty.
Sourcepub async fn get_auth(&self, must_be_active: bool) -> WalletResult<AuthId>
pub async fn get_auth(&self, must_be_active: bool) -> WalletResult<AuthId>
Builds an AuthId for the manager’s identity key.
If must_be_active is true and the manager is not yet available,
returns WERR_NOT_ACTIVE.
Sourcepub async fn get_user_id(&self) -> WalletResult<i64>
pub async fn get_user_id(&self) -> WalletResult<i64>
Returns the user_id from the active store’s cached user.
Sourcepub async fn get_active(&self) -> WalletResult<Arc<dyn WalletStorageProvider>>
pub async fn get_active(&self) -> WalletResult<Arc<dyn WalletStorageProvider>>
Returns a clone of the active Arc<dyn WalletStorageProvider>.
Errors if make_available() has not been called.
Sourcepub async fn make_available(&self) -> WalletResult<Settings>
pub async fn make_available(&self) -> WalletResult<Settings>
Initialize all stores and partition them into active/backups/conflicting.
Idempotent — returns cached active settings on subsequent calls.
Uses reader_lock as the idempotency guard to prevent concurrent re-init.
Sourcepub async fn acquire_reader(&self) -> WalletResult<MutexGuard<'_, ()>>
pub async fn acquire_reader(&self) -> WalletResult<MutexGuard<'_, ()>>
Acquire the reader lock (level 1).
Auto-initializes via make_available() if not yet available.
The reader lock is acquired AFTER initialization so that initialization
itself can serialize via the same reader_lock.
Sourcepub async fn acquire_writer(
&self,
) -> WalletResult<(MutexGuard<'_, ()>, MutexGuard<'_, ()>)>
pub async fn acquire_writer( &self, ) -> WalletResult<(MutexGuard<'_, ()>, MutexGuard<'_, ()>)>
Acquire the reader + writer locks (levels 1 and 2).
Auto-initializes via make_available() if not yet available.
Sourcepub async fn acquire_sync(
&self,
) -> WalletResult<(MutexGuard<'_, ()>, MutexGuard<'_, ()>, MutexGuard<'_, ()>)>
pub async fn acquire_sync( &self, ) -> WalletResult<(MutexGuard<'_, ()>, MutexGuard<'_, ()>, MutexGuard<'_, ()>)>
Acquire reader + writer + sync locks (levels 1, 2, and 3).
Auto-initializes via make_available() if not yet available.
Sourcepub async fn acquire_storage_provider(
&self,
) -> WalletResult<(MutexGuard<'_, ()>, MutexGuard<'_, ()>, MutexGuard<'_, ()>, MutexGuard<'_, ()>)>
pub async fn acquire_storage_provider( &self, ) -> WalletResult<(MutexGuard<'_, ()>, MutexGuard<'_, ()>, MutexGuard<'_, ()>, MutexGuard<'_, ()>)>
Acquire all four locks (levels 1, 2, 3, and 4).
Auto-initializes via make_available() if not yet available.
Sourcepub async fn destroy(&self) -> WalletResult<()>
pub async fn destroy(&self) -> WalletResult<()>
Destroy all stores, cleaning up all resources.
Sourcepub async fn get_services_ref(&self) -> WalletResult<Arc<dyn WalletServices>>
pub async fn get_services_ref(&self) -> WalletResult<Arc<dyn WalletServices>>
Get wallet services.
Sourcepub async fn set_services(&self, services: Arc<dyn WalletServices>)
pub async fn set_services(&self, services: Arc<dyn WalletServices>)
Set wallet services.
Sourcepub async fn list_actions(
&self,
auth: &AuthId,
args: &ListActionsArgs,
) -> WalletResult<ListActionsResult>
pub async fn list_actions( &self, auth: &AuthId, args: &ListActionsArgs, ) -> WalletResult<ListActionsResult>
List wallet actions (transactions) with filtering and pagination.
Sourcepub async fn list_outputs(
&self,
auth: &AuthId,
args: &ListOutputsArgs,
) -> WalletResult<ListOutputsResult>
pub async fn list_outputs( &self, auth: &AuthId, args: &ListOutputsArgs, ) -> WalletResult<ListOutputsResult>
List outputs with basket/tag filtering.
Sourcepub async fn list_certificates(
&self,
auth: &AuthId,
args: &ListCertificatesArgs,
) -> WalletResult<ListCertificatesResult>
pub async fn list_certificates( &self, auth: &AuthId, args: &ListCertificatesArgs, ) -> WalletResult<ListCertificatesResult>
List certificates with certifier/type filtering.
Sourcepub async fn find_certificates_auth(
&self,
auth: &AuthId,
args: &FindCertificatesArgs,
) -> WalletResult<Vec<Certificate>>
pub async fn find_certificates_auth( &self, auth: &AuthId, args: &FindCertificatesArgs, ) -> WalletResult<Vec<Certificate>>
Find certificates scoped to the given auth identity.
Sourcepub async fn find_output_baskets_auth(
&self,
auth: &AuthId,
args: &FindOutputBasketsArgs,
) -> WalletResult<Vec<OutputBasket>>
pub async fn find_output_baskets_auth( &self, auth: &AuthId, args: &FindOutputBasketsArgs, ) -> WalletResult<Vec<OutputBasket>>
Find output baskets scoped to the given auth identity.
Sourcepub async fn find_outputs_auth(
&self,
auth: &AuthId,
args: &FindOutputsArgs,
) -> WalletResult<Vec<Output>>
pub async fn find_outputs_auth( &self, auth: &AuthId, args: &FindOutputsArgs, ) -> WalletResult<Vec<Output>>
Find outputs scoped to the given auth identity.
Sourcepub async fn find_proven_tx_reqs(
&self,
args: &FindProvenTxReqsArgs,
) -> WalletResult<Vec<ProvenTxReq>>
pub async fn find_proven_tx_reqs( &self, args: &FindProvenTxReqsArgs, ) -> WalletResult<Vec<ProvenTxReq>>
Find proven transaction requests.
Sourcepub async fn abort_action(
&self,
auth: &AuthId,
args: &AbortActionArgs,
) -> WalletResult<AbortActionResult>
pub async fn abort_action( &self, auth: &AuthId, args: &AbortActionArgs, ) -> WalletResult<AbortActionResult>
Abort (cancel) a transaction by reference.
Sourcepub async fn create_action(
&self,
auth: &AuthId,
args: &StorageCreateActionArgs,
) -> WalletResult<StorageCreateActionResult>
pub async fn create_action( &self, auth: &AuthId, args: &StorageCreateActionArgs, ) -> WalletResult<StorageCreateActionResult>
Create a new transaction in storage.
Sourcepub async fn process_action(
&self,
auth: &AuthId,
args: &StorageProcessActionArgs,
) -> WalletResult<StorageProcessActionResult>
pub async fn process_action( &self, auth: &AuthId, args: &StorageProcessActionArgs, ) -> WalletResult<StorageProcessActionResult>
Process (commit) a signed transaction to storage.
Sourcepub async fn internalize_action(
&self,
auth: &AuthId,
args: &StorageInternalizeActionArgs,
services: &dyn WalletServices,
) -> WalletResult<StorageInternalizeActionResult>
pub async fn internalize_action( &self, auth: &AuthId, args: &StorageInternalizeActionArgs, services: &dyn WalletServices, ) -> WalletResult<StorageInternalizeActionResult>
Internalize outputs from an external transaction.
Sourcepub async fn insert_certificate_auth(
&self,
auth: &AuthId,
certificate: &Certificate,
) -> WalletResult<i64>
pub async fn insert_certificate_auth( &self, auth: &AuthId, certificate: &Certificate, ) -> WalletResult<i64>
Insert a certificate scoped to the given auth identity.
Sourcepub async fn relinquish_certificate(
&self,
auth: &AuthId,
args: &RelinquishCertificateArgs,
) -> WalletResult<i64>
pub async fn relinquish_certificate( &self, auth: &AuthId, args: &RelinquishCertificateArgs, ) -> WalletResult<i64>
Relinquish (soft-delete) a certificate by marking it deleted.
Sourcepub async fn relinquish_output(
&self,
auth: &AuthId,
args: &RelinquishOutputArgs,
) -> WalletResult<i64>
pub async fn relinquish_output( &self, auth: &AuthId, args: &RelinquishOutputArgs, ) -> WalletResult<i64>
Relinquish (remove from basket) an output by outpoint.
pub async fn find_or_insert_user( &self, identity_key: &str, ) -> WalletResult<(User, bool)>
pub async fn get_sync_chunk( &self, args: &RequestSyncChunkArgs, ) -> WalletResult<SyncChunk>
pub async fn process_sync_chunk( &self, args: &RequestSyncChunkArgs, chunk: &SyncChunk, ) -> WalletResult<ProcessSyncChunkResult>
pub async fn find_user_by_identity_key( &self, key: &str, ) -> WalletResult<Option<User>>
pub async fn find_certificates_storage( &self, args: &FindCertificatesArgs, ) -> WalletResult<Vec<Certificate>>
pub async fn find_certificate_fields( &self, args: &FindCertificateFieldsArgs, ) -> WalletResult<Vec<CertificateField>>
pub async fn find_outputs_storage( &self, args: &FindOutputsArgs, ) -> WalletResult<Vec<Output>>
Sourcepub async fn find_outputs(
&self,
args: &FindOutputsArgs,
) -> WalletResult<Vec<Output>>
pub async fn find_outputs( &self, args: &FindOutputsArgs, ) -> WalletResult<Vec<Output>>
Find outputs (signer pipeline alias).
Sourcepub async fn update_output(
&self,
id: i64,
update: &OutputPartial,
) -> WalletResult<i64>
pub async fn update_output( &self, id: i64, update: &OutputPartial, ) -> WalletResult<i64>
Update an output by ID.
pub async fn insert_certificate_storage( &self, cert: &Certificate, ) -> WalletResult<i64>
pub async fn insert_certificate_field_storage( &self, field: &CertificateField, ) -> WalletResult<()>
pub async fn find_proven_txs( &self, args: &FindProvenTxsArgs, ) -> WalletResult<Vec<ProvenTx>>
pub async fn find_transactions( &self, args: &FindTransactionsArgs, ) -> WalletResult<Vec<Transaction>>
pub async fn update_proven_tx_req( &self, id: i64, update: &ProvenTxReqPartial, ) -> WalletResult<i64>
pub async fn update_proven_tx( &self, id: i64, update: &ProvenTxPartial, ) -> WalletResult<i64>
pub async fn update_transaction( &self, id: i64, update: &TransactionPartial, ) -> WalletResult<i64>
pub async fn update_transaction_status( &self, txid: &str, new_status: TransactionStatus, ) -> WalletResult<()>
pub async fn update_proven_tx_req_with_new_proven_tx( &self, req_id: i64, proven_tx: &ProvenTx, ) -> WalletResult<i64>
pub async fn insert_monitor_event( &self, event: &MonitorEvent, ) -> WalletResult<i64>
pub async fn admin_stats(&self, auth_id: &str) -> WalletResult<AdminStatsResult>
pub async fn purge_data(&self, params: &PurgeParams) -> WalletResult<String>
pub async fn review_status( &self, aged_limit: NaiveDateTime, ) -> WalletResult<String>
pub async fn get_storage_identity_key(&self) -> WalletResult<String>
Sourcepub async fn get_stores(&self) -> Vec<WalletStorageInfo>
pub async fn get_stores(&self) -> Vec<WalletStorageInfo>
Returns metadata for all registered storage providers.
Matches TS getStores(): iterates all stores and returns a WalletStorageInfo
for each, including which is active, which are backups, and which are conflicting.
Sourcepub async fn get_store_endpoint_url(
&self,
storage_identity_key: &str,
) -> Option<String>
pub async fn get_store_endpoint_url( &self, storage_identity_key: &str, ) -> Option<String>
Returns the remote endpoint URL for the store with the given identity key.
Matches TS getStoreEndpointURL(storageIdentityKey).
Returns None for local SQLite stores and for unknown identity keys.
Sourcepub async fn reprove_proven(
&self,
ptx: &ProvenTx,
no_update: bool,
) -> WalletResult<ReproveProvenResult>
pub async fn reprove_proven( &self, ptx: &ProvenTx, no_update: bool, ) -> WalletResult<ReproveProvenResult>
Re-validate the merkle proof for a single ProvenTx record.
Matches TS reproveProven(ptx, noUpdate?):
- Fetches a fresh merkle path from WalletServices.
- Validates it against the current chain tracker.
- If valid and
no_updateis false, persists the updated record to active storage. - Returns a
ReproveProvenResultindicating updated/unchanged/unavailable.
This method must be called while the StorageProvider lock is already held
(the caller’s responsibility — reprove_header acquires it before calling here).
Sourcepub async fn reprove_header(
&self,
deactivated_hash: &str,
) -> WalletResult<ReproveHeaderResult>
pub async fn reprove_header( &self, deactivated_hash: &str, ) -> WalletResult<ReproveHeaderResult>
Re-prove all ProvenTx records associated with a deactivated block hash.
Matches TS reproveHeader(deactivatedHash):
- Runs under StorageProvider lock (all four locks).
- Finds all ProvenTx records with block_hash == deactivated_hash.
- Calls
reprove_provenfor each (no_update=true for individual calls). - Bulk-updates all successfully reproved records in a single pass.
- Returns
ReproveHeaderResultwith updated/unchanged/unavailable partitions.
Sourcepub async fn sync_to_writer(
&self,
writer: &dyn WalletStorageProvider,
reader: &dyn WalletStorageProvider,
writer_settings: &Settings,
reader_settings: &Settings,
prog_log: Option<&(dyn Fn(&str) -> String + Send + Sync)>,
) -> WalletResult<(i64, i64, String)>
pub async fn sync_to_writer( &self, writer: &dyn WalletStorageProvider, reader: &dyn WalletStorageProvider, writer_settings: &Settings, reader_settings: &Settings, prog_log: Option<&(dyn Fn(&str) -> String + Send + Sync)>, ) -> WalletResult<(i64, i64, String)>
Sync entities from reader into writer using chunked getSyncChunk/processSyncChunk.
Loops until processSyncChunk returns done=true, accumulating insert/update counts.
Caller must hold the sync lock (acquired by update_backups or sync_from_reader).
§Arguments
writer- Storage receiving the sync data.reader- Storage providing the sync data.writer_settings- Cached settings for the writer (to_storage_identity_key).reader_settings- Cached settings for the reader (from_storage_identity_key).prog_log- Optional progress callback. If Some, called after each chunk with a progress string. Returns the accumulated log of all callback return values.
Returns (total_inserts, total_updates, log_string).
Sourcepub async fn sync_from_reader(
&self,
reader_identity_key: &str,
writer: &dyn WalletStorageProvider,
reader: &dyn WalletStorageProvider,
writer_settings: &Settings,
reader_settings: &Settings,
prog_log: Option<&(dyn Fn(&str) -> String + Send + Sync)>,
) -> WalletResult<(i64, i64, String)>
pub async fn sync_from_reader( &self, reader_identity_key: &str, writer: &dyn WalletStorageProvider, reader: &dyn WalletStorageProvider, writer_settings: &Settings, reader_settings: &Settings, prog_log: Option<&(dyn Fn(&str) -> String + Send + Sync)>, ) -> WalletResult<(i64, i64, String)>
Sync entities from reader into writer with active_storage override protection.
Identical to sync_to_writer except that before calling writer.process_sync_chunk,
the chunk.user.active_storage field is overridden with the writer’s cached
user.active_storage. This prevents the reader’s active_storage from clobbering
the writer’s during sync (Pitfall 5 from the research).
reader_identity_key must match this manager’s identity key; otherwise returns
WERR_UNAUTHORIZED. This mirrors the TS WalletStorageManager.syncFromReader check.
Sourcepub async fn update_backups(
&self,
prog_log: Option<&(dyn Fn(&str) -> String + Send + Sync)>,
) -> WalletResult<(i64, i64, String)>
pub async fn update_backups( &self, prog_log: Option<&(dyn Fn(&str) -> String + Send + Sync)>, ) -> WalletResult<(i64, i64, String)>
Sync all backup stores from the active store.
Acquires sync-level locks, iterates backup_indices, and calls
sync_to_writer(backup, active, ...) for each backup. Per-backup errors
are logged as warnings and do not block other backups.
Returns (total_inserts, total_updates, accumulated_log).
Sourcepub async fn set_active(
&self,
storage_identity_key: &str,
prog_log: Option<&(dyn Fn(&str) -> String + Send + Sync)>,
) -> WalletResult<String>
pub async fn set_active( &self, storage_identity_key: &str, prog_log: Option<&(dyn Fn(&str) -> String + Send + Sync)>, ) -> WalletResult<String>
Switch the active store to the one identified by storage_identity_key.
Implements the TS setActive(storageIdentityKey, progLog?) algorithm (8 steps):
- Validate the target store is registered.
- Early-return “unchanged” if already active and enabled.
- Acquire sync lock.
- Merge any conflicting-active stores into the new active via
sync_to_writer. - Determine backup_source (new_active if conflicts existed, else current_active).
- Call provider-level
set_activeon backup_source to persistuser.active_storage. - Propagate state to all other stores via
sync_to_writer. - Reset
is_availableand re-partition viado_make_available.
Returns accumulated progress log string on success.
Sourcepub async fn add_wallet_storage_provider(
&self,
provider: Arc<dyn WalletStorageProvider>,
) -> WalletResult<()>
pub async fn add_wallet_storage_provider( &self, provider: Arc<dyn WalletStorageProvider>, ) -> WalletResult<()>
Add a new storage provider at runtime.
Acquires all four locks (storage-provider level), appends the provider
to the stores vec, resets is_available, and re-runs make_available()
to re-partition the updated store list.
Matches TS addWalletStorageProvider(storage).
Sourcepub async fn find_output_baskets(
&self,
args: &FindOutputBasketsArgs,
) -> WalletResult<Vec<OutputBasket>>
pub async fn find_output_baskets( &self, args: &FindOutputBasketsArgs, ) -> WalletResult<Vec<OutputBasket>>
Find or create an output basket by user ID and name.
Sourcepub async fn insert_output_basket(
&self,
basket: &OutputBasket,
) -> WalletResult<i64>
pub async fn insert_output_basket( &self, basket: &OutputBasket, ) -> WalletResult<i64>
Insert an output basket directly (no auth check).
Sourcepub async fn insert_transaction(&self, tx: &Transaction) -> WalletResult<i64>
pub async fn insert_transaction(&self, tx: &Transaction) -> WalletResult<i64>
Insert a transaction directly (no auth check).
Sourcepub async fn insert_output(&self, output: &Output) -> WalletResult<i64>
pub async fn insert_output(&self, output: &Output) -> WalletResult<i64>
Insert an output directly (no auth check).
Auto Trait Implementations§
impl !Freeze for WalletStorageManager
impl !RefUnwindSafe for WalletStorageManager
impl Send for WalletStorageManager
impl Sync for WalletStorageManager
impl Unpin for WalletStorageManager
impl UnsafeUnpin for WalletStorageManager
impl !UnwindSafe for WalletStorageManager
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
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 more