pub struct Context { /* private fields */ }Implementations§
Source§impl Context
impl Context
Sourcepub const VERSION_MAJOR_SCALE: u64 = 100_000
pub const VERSION_MAJOR_SCALE: u64 = 100_000
Semantic peer-dependency versioning scheme (paper §open-problems, peer dependencies).
A provider’s version is a plain u64. The major component lives in
the high bits: major(v) = v / 100_000, and the minimum compatible
floor is the remainder v % 100_000 within that major. An inject
constrained with requirement = M * 100_000 + f is satisfied by a
provider of version p if and only if
- the provider exists and is available, and
major(p) == major(requirement)(same-major compatibility — peer dependencies never bind across a breaking boundary), andp >= requirement(the provider is at least the requested floor; under equal majors this is exactly “remainder >= floor”).
Any mismatch leaves the inject unsatisfied: the dependent fiber
goes, and stays, Inactive rather than silently binding a wrong
version. Providers installed through legacy Self::provide carry
version 0, so they satisfy only unconstrained injects; migrate them to
Self::provide_versioned to opt into constraint matching.
pub fn new_root() -> Arc<Context> ⓘ
pub fn extend(self: &Arc<Context>) -> Arc<Context> ⓘ
pub fn isolate_type( self: &Arc<Context>, tid: TypeId, label: impl Into<String>, ) -> Arc<Context> ⓘ
pub fn isolate<T>(self: &Arc<Context>, label: impl Into<String>) -> Arc<Context> ⓘwhere
T: Service,
pub fn intercept<T>(self: &Arc<Context>, val: T) -> Arc<Context> ⓘwhere
T: Service,
Sourcepub fn provide_versioned<T>(
self: &Arc<Context>,
value: T,
version: u64,
) -> Arc<T> ⓘ
pub fn provide_versioned<T>( self: &Arc<Context>, value: T, version: u64, ) -> Arc<T> ⓘ
Provide value under T together with a semantic peer-dependency
version. See the Self::VERSION_MAJOR_SCALE documentation for the
exact satisfaction scheme. Ownership/undo semantics are identical to
Self::provide.
Sourcepub fn provider_version(&self, tid: TypeId) -> u64
pub fn provider_version(&self, tid: TypeId) -> u64
The semantic peer-dependency version recorded for tid, walking the
parent chain like Self::get_version. Returns 0 when no value was
provided or when it was installed through an unversioned path.
Distinct from Self::get_version, which counts structural store
mutations of tid and drives epoch strings; this reads the declared
compatibility contract used by version-constrained injects.
pub fn provide<T>(self: &Arc<Context>, svc: T) -> Arc<T> ⓘwhere
T: Service,
Sourcepub fn remove<T>(self: &Arc<Context>) -> Result<Option<Arc<T>>, CordisError>where
T: Service,
pub fn remove<T>(self: &Arc<Context>) -> Result<Option<Arc<T>>, CordisError>where
T: Service,
Remove a service from the store and trigger deactivation cascade.
Guarded withdrawal: when a RegistryService is present and active
consumer fibers still resolve T in this isolate realm, removal is
refused with a guarded withdrawal configuration error instead of
pulling the dependency out from under them. Internal rollback paths
(fiber undo stacks) bypass the guard via Self::remove_forced.
Pushes the inverse (re-provide) onto the fiber’s accumulator for LIFO
reversal once the guard permits the removal.
Sourcepub fn get_relaxed<T>(&self) -> Option<Arc<T>>where
T: Service,
pub fn get_relaxed<T>(&self) -> Option<Arc<T>>where
T: Service,
Relaxed read: like Self::get, but a locally-owned provider whose
owner fiber rests in a TRANSITIONING state (Loading, Reloading,
Unloading, or reactive Pending) still resolves. Strict Self::get
refuses those so consumers never observe mid-transition values;
lifecycle/observer code (and tests) use this to inspect the value that
is about to serve or was just retracted during transitions.
Terminal resting states (Failed, disposed) and missing owners stay
refused exactly as in Self::get.
pub fn get<T>(&self) -> Option<Arc<T>>where
T: Service,
pub fn get_version(&self, tid: TypeId) -> u64
pub fn isolate_label(&self, tid: TypeId) -> Option<String>
Sourcepub fn provided_type_ids(&self) -> Vec<TypeId>
pub fn provided_type_ids(&self) -> Vec<TypeId>
TypeIds currently provided in this context’s store (not parent/intercept).
Sourcepub fn bind_isolate(&self, tid: TypeId, label: impl Into<String>)
pub fn bind_isolate(&self, tid: TypeId, label: impl Into<String>)
Record an isolate namespace on this context without forking a child.
Loader uses this after a factory provides so get_isolated can find
the new service under Entry.isolate while get still works on boot.
Sourcepub fn bind_intercept<T>(&self, val: T)where
T: Service,
pub fn bind_intercept<T>(&self, val: T)where
T: Service,
Record an intercept override on this context without forking a child.
APPENDS a layer: the effective value becomes the innermost (this one)
while outer layers stay inspectable through Self::intercept_chain.
Sourcepub fn register_accessor(
self: &Arc<Context>,
name: &str,
accessor: Accessor,
) -> Result<EffectHandle, CordisError>
pub fn register_accessor( self: &Arc<Context>, name: &str, accessor: Accessor, ) -> Result<EffectHandle, CordisError>
Register a computed property under name beside the TypeId service
store. Duplicate declarations (including alias collisions) are
rejected with CordisError::DuplicateProvider. The returned
EffectHandle removes the declaration (and any aliases) on
dispose.
Accessor reads/writes BYPASS the internal/get / internal/set
intercept waterfalls entirely — resolving an accessor never consults
or re-enters a veto chain.
Sourcepub fn alias(
self: &Arc<Context>,
alias: &str,
target: &str,
) -> Result<(), CordisError>
pub fn alias( self: &Arc<Context>, alias: &str, target: &str, ) -> Result<(), CordisError>
Bind alias as an alternate name resolving through the SAME
registration as target — same getter/setter, disposed together.
Sourcepub fn read_property(
&self,
name: &str,
) -> Result<Option<Arc<dyn Any + Send + Sync>>, CordisError>
pub fn read_property( &self, name: &str, ) -> Result<Option<Arc<dyn Any + Send + Sync>>, CordisError>
Resolve name through its accessor (bypassing all interception
waterfalls). Undeclared names and write-only properties resolve
None; use Self::read_property_typed for downcast checking.
Sourcepub fn read_property_typed<T>(
&self,
name: &str,
) -> Result<Option<Arc<T>>, CordisError>
pub fn read_property_typed<T>( &self, name: &str, ) -> Result<Option<Arc<T>>, CordisError>
Typed accessor read: a value that fails to downcast to T is
CordisError::PropertyTypeMismatch, never a silent None.
Sourcepub fn write_property(
self: &Arc<Context>,
name: &str,
value: Arc<dyn Any + Send + Sync>,
) -> Result<(), CordisError>
pub fn write_property( self: &Arc<Context>, name: &str, value: Arc<dyn Any + Send + Sync>, ) -> Result<(), CordisError>
Write value to name through its accessor. A fully undeclared
name is refused MissingService-style (“cannot set property”); a
declared-but-setter-less name is refused
CordisError::ReadOnlyProperty. Never consults the
internal/set waterfall.
Sourcepub fn intercept_chain(&self, tid: TypeId) -> Vec<Arc<dyn Any + Send + Sync>>
pub fn intercept_chain(&self, tid: TypeId) -> Vec<Arc<dyn Any + Send + Sync>>
All intercept layers for tid visible from this frame, ordered
OUTERMOST..INNERMOST (ancestor frames first, this frame’s appended
layers last). The innermost element is the effective value every
existing single-value getter returns.
Sourcepub fn chains_structurally_equal(
a: &[Arc<dyn Any + Send + Sync>],
b: &[Arc<dyn Any + Send + Sync>],
) -> bool
pub fn chains_structurally_equal( a: &[Arc<dyn Any + Send + Sync>], b: &[Arc<dyn Any + Send + Sync>], ) -> bool
Structural equality for two intercepted chains, used by
restart-decision comparisons: same length and every layer pair the
SAME shared instance (Arc::ptr_eq). Erased values carry no
comparable contract, so identity is the only honest structural test;
freshly-built values therefore compare unequal by design.
Sourcepub fn get_isolated<T>(&self, label: &str) -> Option<Arc<T>>where
T: Service,
pub fn get_isolated<T>(&self, label: &str) -> Option<Arc<T>>where
T: Service,
Retrieve a service only if it was provided in a context whose isolate
namespace for T matches label. Walks the context chain but skips
any frame whose isolate label for T differs from the requested one.
Sourcepub fn with_intercept<T>(self: &Arc<Context>, val: T) -> Arc<Context> ⓘwhere
T: Service,
pub fn with_intercept<T>(self: &Arc<Context>, val: T) -> Arc<Context> ⓘwhere
T: Service,
Create a child context where get::<T>() returns val as an override.
Alias for intercept — explicitly named for per-request model pinning.
Sourcepub async fn inject<T>(self: &Arc<Context>) -> Arc<T> ⓘwhere
T: Service,
pub async fn inject<T>(self: &Arc<Context>) -> Arc<T> ⓘwhere
T: Service,
Wait until T is provided on this context (or a parent). Returns the service.
If ReflectService is on the context, wait on its TypeId notifier
(ensure_notifier + changed) so provide → notify unblocks without
polling. If the sender is dropped, or ReflectService is absent, fall
through to a 5ms poll loop so tests without Reflect still complete.
pub fn provide_arc<T>(self: &Arc<Context>, svc: Arc<T>) -> Arc<T> ⓘwhere
T: Service,
pub fn fiber(&self) -> Arc<Fiber> ⓘ
pub fn snapshot_len(&self) -> usize
pub async fn plugin<S>(self: &Arc<Context>, svc: S) -> Result<u64, CordisError>where
S: Service,
pub async fn plugin_with<P>(
self: &Arc<Context>,
plugin: P,
config: <P as Plugin>::Config,
) -> Result<u64, CordisError>where
P: Plugin,
Source§impl Context
impl Context
Sourcepub fn log_with<F>(&self, name: &str, kind: LogKind, assemble: F)
pub fn log_with<F>(&self, name: &str, kind: LogKind, assemble: F)
Gated write with lazy argument assembly through the provided
LoggerService (no-op when absent). The intercept channel is
consulted on self, so per-fiber overrides apply to child contexts.
Sourcepub fn log(&self, name: &str, kind: LogKind, args: Vec<LogArg>)
pub fn log(&self, name: &str, kind: LogKind, args: Vec<LogArg>)
Gated write with pre-built arguments.
pub fn info(&self, name: &str, args: Vec<LogArg>)
pub fn warn(&self, name: &str, args: Vec<LogArg>)
pub fn debug(&self, name: &str, args: Vec<LogArg>)
pub fn error(&self, name: &str, args: Vec<LogArg>)
Auto Trait Implementations§
impl !Freeze for Context
impl !RefUnwindSafe for Context
impl !UnwindSafe for Context
impl Send for Context
impl Sync for Context
impl Unpin for Context
impl UnsafeUnpin for Context
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
impl<T> ErasedDestructor for Twhere
T: 'static,
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 moreimpl<T> MaybeSendSync for T
Source§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
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
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.