pub struct MoonStorage { /* private fields */ }Expand description
StoragePort backed by a single Moon RESP connection manager.
initialized_scopes tracks which scopes have had their FT indices and graph
key created (lazy init on first write). Mutex is held only during the
brief check + insert — never across .await points.
Implementations§
Source§impl MoonStorage
impl MoonStorage
Sourcepub async fn repair_unindexable_vectors(
&self,
scope: &Scope,
index: &str,
dry_run: bool,
) -> Result<VectorRepairReport, StorageError>
pub async fn repair_unindexable_vectors( &self, scope: &Scope, index: &str, dry_run: bool, ) -> Result<VectorRepairReport, StorageError>
Removes the vec field from every row in scope/index whose stored
embedding cannot be a KNN candidate, leaving the rest of the row alone.
Pass dry_run = true to count the damage without touching the store —
an operator pointing this at a production scope is owed the number
before the mutation.
The scan is bounded by the per-scope FT index name, so a repair of one tenant cannot read or write another tenant’s rows.
Source§impl MoonStorage
impl MoonStorage
Sourcepub async fn connect(url: &str) -> Result<MoonStorage, StorageError>
pub async fn connect(url: &str) -> Result<MoonStorage, StorageError>
Open a connection to Moon at url (moon://host:port[?ws=workspace]),
creating FT vector indices at the default dimension
(client::DEFAULT_VECTOR_DIM = 768, matching EmbeddingGemma-300M).
Sourcepub async fn connect_with_dim(
url: &str,
dim: usize,
) -> Result<MoonStorage, StorageError>
pub async fn connect_with_dim( url: &str, dim: usize, ) -> Result<MoonStorage, StorageError>
Like MoonStorage::connect, but creates the FT vector indices at
dim instead of the default 768. dim MUST be > 0. Moon’s
FT.CREATE has no upper cap, so a 1536-d embedder (OpenAI
text-embedding-3) works against Moon out of the box.
§Operator footgun — existing index won’t auto-resize
Moon’s FT.CREATE is idempotent and does NOT update an existing
index’s schema. If a Moon instance already holds a 768-d chunks
index from a prior run, reopening with a 1536-d embedder leaves the
768-d index in place; the mismatch surfaces only on the first vector
write. Drop the stale index first (FT.DROPINDEX <name>).
Sourcepub fn client(&self) -> &MoonClient
pub fn client(&self) -> &MoonClient
Borrow the underlying client (used by integration tests).
Trait Implementations§
Source§impl Clone for MoonStorage
impl Clone for MoonStorage
Source§fn clone(&self) -> MoonStorage
fn clone(&self) -> MoonStorage
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for MoonStorage
impl Debug for MoonStorage
Source§impl KeywordPort for MoonStorage
impl KeywordPort for MoonStorage
Source§fn keyword_search<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
index: &'life2 str,
query: &'life3 str,
k: usize,
filter: Option<&'life4 Filter>,
as_of: Option<Hlc>,
) -> Pin<Box<dyn Future<Output = Result<Vec<KeywordHit>, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
MoonStorage: 'async_trait,
fn keyword_search<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
index: &'life2 str,
query: &'life3 str,
k: usize,
filter: Option<&'life4 Filter>,
as_of: Option<Hlc>,
) -> Pin<Box<dyn Future<Output = Result<Vec<KeywordHit>, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
MoonStorage: 'async_trait,
Wave 2.5A: KeywordPort::keyword_search now carries scope: &Scope
(RFC 0001 §3.4 amendment). The Moon backend threads scope through to
keyword::keyword_search which routes to the per-scope FT index
(ft_index_name(scope, index)). Previously this impl used Scope::dev()
as a placeholder — that placeholder is now replaced by the caller-supplied scope.
Source§impl StoragePort for MoonStorage
impl StoragePort for MoonStorage
Source§fn atomic_write<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
ops: &'life2 [WriteOp],
) -> Pin<Box<dyn Future<Output = Result<Lsn, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
fn atomic_write<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
ops: &'life2 [WriteOp],
) -> Pin<Box<dyn Future<Output = Result<Lsn, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
RFC 0001 Wave 1C: lazy per-scope init before writing, then route all ops through scope-prefixed keys / indices.
Source§fn health_check<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
MoonStorage: 'async_trait,
fn health_check<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
MoonStorage: 'async_trait,
observability-rollout-maturity — override the additive default with a
real Moon PING so a dead/stalled backend surfaces as Err on the
/healthz rollout-cutback probe. Bounded by LUNARIS_MOON_OP_TIMEOUT.
Source§fn maintenance_hint<'life0, 'life1, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
hint: MaintenanceHint,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
MoonStorage: 'async_trait,
fn maintenance_hint<'life0, 'life1, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
hint: MaintenanceHint,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
MoonStorage: 'async_trait,
moon-v051-perf-exploit W1: Moon override of the default no-op. On
BulkIngestComplete at/above LUNARIS_MOON_COMPACT_MIN vector
upserts, force-compacts the scope’s vector indexes so recall hits the
compacted HNSW + exact-rerank segments instead of brute-force mutable
scans — see vector::maybe_compact_after_bulk_ingest for the full
contract (missing-index tolerance, threshold parsing).
Source§fn supports_historical_kv_reads(&self) -> bool
fn supports_historical_kv_reads(&self) -> bool
Moon has no KV version chain — see crate::as_of for the full
rationale and the upstream TemporalKvIndex path. Declaring this
false is one half of the contract; kv::read_as_of refusing a
historical pin with StorageError::NotSupported is the other.
Source§fn lookup_by_dedupe_key<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
dedupe_key: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Lsn>, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
fn lookup_by_dedupe_key<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
dedupe_key: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Lsn>, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
HOOK-05 idempotency sidecar (ADD task moon-parity-honesty): gives Moon
a real dedupe-key lookup. Before this, the trait-default Ok(None)
fall-through minted duplicate episodes for every replayed dedupe key
(proved live 2026-07-14) — idempotency was documented as available on
the embedded backend only, a boundary this closes.
Source§fn queue_depth<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
topic: &'life2 str,
partition: u16,
) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
fn queue_depth<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
topic: &'life2 str,
partition: u16,
) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
Plan 04 D-12 — see crate::queue::queue_length (private) for the raw
MQ.LENGTH escape hatch rationale.
Source§fn queue_range<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
topic: &'life2 str,
partition: u16,
from_ms: Option<u64>,
to_ms: Option<u64>,
limit: usize,
) -> Pin<Box<dyn Future<Output = Result<Vec<QueueMsg>, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
fn queue_range<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
topic: &'life2 str,
partition: u16,
from_ms: Option<u64>,
to_ms: Option<u64>,
limit: usize,
) -> Pin<Box<dyn Future<Output = Result<Vec<QueueMsg>, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
W4.6 / D6.3 — non-destructive range read; see
crate::queue::queue_range for why this is XRANGE and not the MQ
consumer surface.
Source§fn list_scopes<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
prefix: Option<&'life1 str>,
limit: usize,
cursor: Option<&'life2 str>,
) -> Pin<Box<dyn Future<Output = Result<ScopePage, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
fn list_scopes<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
prefix: Option<&'life1 str>,
limit: usize,
cursor: Option<&'life2 str>,
) -> Pin<Box<dyn Future<Output = Result<ScopePage, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
Cross-scope enumeration via SCAN MATCH lunaris:* + key parse.
Q-U2 lock — lazy SCAN-derived. See crate::scopes for the cursor
model and the Moon-SCAN-cursor vs scope-string-cursor tradeoff.
Source§fn invalidate_range<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
index: &'life2 str,
node_id_field: &'life3 str,
node_id_value: &'life4 str,
hlc_wall_field: &'life5 str,
hlc_wall_lo_inclusive: i64,
hlc_wall_hi_inclusive: i64,
) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
'life5: 'async_trait,
MoonStorage: 'async_trait,
fn invalidate_range<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
index: &'life2 str,
node_id_field: &'life3 str,
node_id_value: &'life4 str,
hlc_wall_field: &'life5 str,
hlc_wall_lo_inclusive: i64,
hlc_wall_hi_inclusive: i64,
) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
'life5: 'async_trait,
MoonStorage: 'async_trait,
Bulk-invalidate FT index records via FT.INVALIDATE_RANGE.
§Wire shape
FT.INVALIDATE_RANGE <index> <node_id_field> <node_id_value>
<hlc_wall_field> <hlc_wall_lo> <hlc_wall_hi>Returns the integer count of deleted records as u64.
§Escape hatch
moon-client v0.1.x does not expose a typed wrapper for
FT.INVALIDATE_RANGE. We reach the underlying
redis::aio::MultiplexedConnection via MoonClient::inner_mut() on a
local clone — the same documented pattern used by the HSCAN escape hatch
in kv.rs (the only other permitted raw-RESP site in this crate per
Phase 1.5 STORE-09 constraints).
§Error mapping
- Moon
WRONGTYPE(index does not exist) →StorageError::Backendcontaining"WRONGTYPE". TheLunaris::invalidate_rangefan-out treats this as warn-and-skip (degraded mode). - Any other Moon error →
StorageError::Backend.
Source§fn vector_search<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
index: &'life2 str,
query: &'life3 [f32],
k: usize,
filter: Option<&'life4 Filter>,
as_of: Option<Hlc>,
rerank: bool,
) -> Pin<Box<dyn Future<Output = Result<Vec<VectorHit>, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
MoonStorage: 'async_trait,
fn vector_search<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
index: &'life2 str,
query: &'life3 [f32],
k: usize,
filter: Option<&'life4 Filter>,
as_of: Option<Hlc>,
rerank: bool,
) -> Pin<Box<dyn Future<Output = Result<Vec<VectorHit>, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
MoonStorage: 'async_trait,
rerank=true is a HINT — backends without
native rerank should return rerank_applied=false in each hit; the retriever
may then apply rerank downstream or skip per degraded_fallback. Read moreSource§fn graph_traverse<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
query: &'life2 CypherQuery,
as_of: Option<Hlc>,
) -> Pin<Box<dyn Future<Output = Result<GraphResult, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
fn graph_traverse<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
query: &'life2 CypherQuery,
as_of: Option<Hlc>,
) -> Pin<Box<dyn Future<Output = Result<GraphResult, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
Err(StorageError::NotSupported(_)); retrievers degrade to vector-only.Source§fn graph_traverse_decayed<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
query: &'life2 CypherQuery,
as_of: Option<Hlc>,
decay: Option<&'life3 GraphDecay>,
) -> Pin<Box<dyn Future<Output = Result<GraphResult, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
MoonStorage: 'async_trait,
fn graph_traverse_decayed<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
query: &'life2 CypherQuery,
as_of: Option<Hlc>,
decay: Option<&'life3 GraphDecay>,
) -> Pin<Box<dyn Future<Output = Result<GraphResult, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
MoonStorage: 'async_trait,
graph-decay-recency, contract v1). Read moreft-navigate-recall,
contract v1): KNN seeds → server-side BFS over the scope graph →
re-ranked hits with hop metadata. Read moreSource§fn hot_keys<'life0, 'async_trait>(
&'life0 self,
count: usize,
) -> Pin<Box<dyn Future<Output = Result<Vec<HotKey>, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
MoonStorage: 'async_trait,
fn hot_keys<'life0, 'async_trait>(
&'life0 self,
count: usize,
) -> Pin<Box<dyn Future<Output = Result<Vec<HotKey>, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
MoonStorage: 'async_trait,
NotSupported, no capability flag;
the lunaris-server poller warns once and goes quiet). Read moreSource§fn scan_range<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
prefix: &'life2 [u8],
as_of: Option<Hlc>,
) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<(Bytes, Bytes), StorageError>> + Send + 'life0>>, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
fn scan_range<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
prefix: &'life2 [u8],
as_of: Option<Hlc>,
) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<(Bytes, Bytes), StorageError>> + Send + 'life0>>, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
Source§fn read_as_of<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
key: &'life2 [u8],
as_of: Hlc,
) -> Pin<Box<dyn Future<Output = Result<Option<Row<Bytes>>, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
fn read_as_of<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
key: &'life2 [u8],
as_of: Hlc,
) -> Pin<Box<dyn Future<Output = Result<Option<Row<Bytes>>, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
Source§fn insert_dedupe_key<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
dedupe_key: &'life2 str,
lsn: Lsn,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
fn insert_dedupe_key<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
dedupe_key: &'life2 str,
lsn: Lsn,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
atomic_write. Read moreSource§fn publish<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
topic: &'life2 str,
partition: u16,
payload: Bytes,
) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
fn publish<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
topic: &'life2 str,
partition: u16,
payload: Bytes,
) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
MoonStorage: 'async_trait,
(topic, partition)).Source§fn subscribe<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
group: &'life2 str,
topic: &'life3 str,
partition: u16,
) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<QueueMsg, StorageError>> + Send>>, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
MoonStorage: 'async_trait,
fn subscribe<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
group: &'life2 str,
topic: &'life3 str,
partition: u16,
) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<QueueMsg, StorageError>> + Send>>, StorageError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
MoonStorage: 'async_trait,
Result<QueueMsg, StorageError> per message;
stream is 'static because subscriptions outlive any single request frame. Read moreSource§fn capabilities(&self) -> StorageCapabilities
fn capabilities(&self) -> StorageCapabilities
Auto Trait Implementations§
impl !RefUnwindSafe for MoonStorage
impl !UnwindSafe for MoonStorage
impl Freeze for MoonStorage
impl Send for MoonStorage
impl Sync for MoonStorage
impl Unpin for MoonStorage
impl UnsafeUnpin for MoonStorage
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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