#[non_exhaustive]pub struct Sim {
pub seed: u64,
/* private fields */
}Expand description
A deterministic simulation handle, constructed from a single u64 seed.
Sim is the day-one public, stability-frozen entry point handed to a
#[sim_test] body. Its seed is public so a
test can assert on or thread it; the injection handles it owns
(SimRng, the clock, Chaos and the mounted app) are private and reached
through accessors, so their internals can evolve wave-over-wave without a
breaking change.
Marked #[non_exhaustive] so future waves can add handles without breaking
construction — always build one via Sim::from_seed.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.seed: u64The seed this simulation was constructed from.
Reproduce a run by exporting AUTUMN_SIM_SEED=0x<seed> (the replay line
printed on panic does this for you).
Implementations§
Source§impl Sim
impl Sim
Sourcepub fn from_seed(seed: u64) -> Self
pub fn from_seed(seed: u64) -> Self
Construct a simulation from seed.
Infallible and cheap: it seeds the RNG and starts the virtual clock but
does not boot a database or an app, so an empty
#[sim_test] runs with zero setup. Mount an app with
build.
Built inside its paused runtime, the sim’s elapsed time starts here.
Built before that runtime, call anchor first thing in
it; #[sim_test] does this for you.
Sourcepub fn anchor(&self)
pub fn anchor(&self)
Start this sim’s elapsed time at tokio’s current instant, if it has not started yet. Call it first thing in the runtime that drives a sim built before that runtime: tokio time that passes before the sim is anchored is not in its elapsed time. Calling it again changes nothing, and outside a runtime it does nothing.
A sim built inside its runtime, or run by
#[sim_test], is anchored already.
Sourcepub fn chaos(&mut self, chaos: Chaos) -> &mut Self
pub fn chaos(&mut self, chaos: Chaos) -> &mut Self
Configure deterministic fault injection for this simulation.
The chaos builder’s hooks (transient DB checkout errors, job duplicate
delivery, clock skew) are installed at build time, each
fault decision drawn from a dedicated seed-derived stream so the same
seed and configuration replay the same fault schedule. A default
Chaos is inactive and changes nothing.
use autumn_web::sim::Chaos;
sim.chaos(Chaos::default().db_transient_errors(0.1).job_duplicate_delivery(0.2));
let client = sim.build(TestApp::new().routes(routes![touch]).jobs(jobs![work]));Sourcepub fn net(&mut self, net: SimNet) -> &mut Self
pub fn net(&mut self, net: SimNet) -> &mut Self
Route the app’s outbound HTTP through a simulated network (issue #2967).
build installs net in the app, so the
crate::http_client::Client extractor sends through it: seeded
latency and drops, partitions, and in-process hosts. Keep a clone to
partition hosts and read SimNet::events later. See net.
Sourcepub const fn seed(&self) -> u64
pub const fn seed(&self) -> u64
The seed this simulation was constructed from.
Provided for API symmetry alongside the public seed
field.
Sourcepub fn rng(&mut self) -> &mut SimRng
pub fn rng(&mut self) -> &mut SimRng
Borrow the seeded deterministic RNG handle.
Draw deterministic values and UUIDs through it — e.g.
SimRng::uuid_v4 / SimRng::next_u64. The same seed always yields
the same draw sequence.
Sourcepub fn seeded_entropy(&self) -> Arc<dyn Entropy> ⓘ
pub fn seeded_entropy(&self) -> Arc<dyn Entropy> ⓘ
Build a shared, seeded Entropy source for this simulation’s seed,
ready to inject into a mounted app via
crate::state::AppState::with_entropy.
build already installs this source in the app it
mounts, unless the test passed its own with
crate::test::TestApp::with_entropy. Use this to seed state you build
yourself.
This is the bridge W3 provides for W2’s app mounting: the app the
simulation drives resolves the crate::entropy::Rng extractor and
every framework-minted identifier (job ids, request ids, idempotency
lock owners, session ids) from this source, so a fixed seed replays the
whole identifier stream byte-for-byte.
The returned source is seeded independently from the rng
handle (both from seed), so drawing from one does not
perturb the other’s sequence.
Sourcepub fn build(&mut self, app: TestApp) -> &TestClient
pub fn build(&mut self, app: TestApp) -> &TestClient
Mount app on the paused runtime with the simulation’s virtual clock
installed, and return the resulting crate::test::TestClient.
The simulation’s virtual clock is threaded in via
crate::test::TestApp::with_clock, so every handler that reads a
crate::time::Clock extractor sees the virtual instant — starting at
the fixed sim epoch (2020-01-01T00:00:00Z) and moving only when
Sim::advance steps it. The built app also starts the in-process job
runtime (the in-memory backend), so run_to_idle
can drain enqueued jobs deterministically, and starts its #[scheduled]
tasks, whose ticks fire as virtual time crosses their deadlines.
Unless app already has an entropy source from
crate::test::TestApp::with_entropy, build installs one seeded from
seed, so framework-minted ids replay from the seed. A
later mount through restart derives a new seed from it,
so a restarted process does not repeat the crashed one’s ids.
Configure app fully before handing it over: routes, jobs, tasks and a
sim database are attached to the crate::test::TestApp before this
call. Do not call crate::test::TestApp::with_clock yourself;
build owns the clock so time stays in lockstep.
The returned borrow is convenient for an immediate request; to interleave
requests with advance / run_to_idle
calls, reach the client through client instead.
let client = sim.build(TestApp::new().routes(routes![hello]).jobs(jobs![work]));
client.get("/hello").send().await.assert_ok();Sourcepub fn kill(&mut self)
pub fn kill(&mut self)
Simulate a process crash: stop the app’s job and scheduler tasks and
drop the mounted app, so in-flight work is cancelled without
completing (the client’s Drop also cancels the runtime’s shutdown
token and clears the global job client), ready for durable recovery on
restart.
This is the kill half of the W5.c crash-recovery primitive (item 7). It
deliberately drops only the app/runtime, never the durable database:
the caller holds the sim’s DB substrate (e.g. an
SqliteSubstrate) and its pool(), so every committed row — crucially
the durable autumn_repository_commit_hooks queue — survives the crash
and is still there when a fresh app is mounted on the same pool.
A crash after build has not run is a no-op.
§Durability boundary (stated plainly)
Under the sqlite sim substrate the app runs the in-memory local
job backend, which is not durable — a kill drops its mid-flight and
still-queued jobs by design, exactly as a real process crash would drop an
in-memory queue. Item 7’s durable guarantee is therefore asserted against
the DB-backed repository commit-hook queue, not the local job queue;
the in-memory job queue’s by-design loss is documented, never pretended
durable. See the crash module docs.
Sourcepub fn restart(&mut self, app: TestApp) -> &TestClient
pub fn restart(&mut self, app: TestApp) -> &TestClient
Restart after a kill: mount a fresh app on the paused
runtime, modelling a process restart on the same durable database.
The caller rebuilds the TestApp against the same substrate pool
(TestApp::new()…with_db(substrate.pool())), so the restarted app sees
every row the crashed process committed. Following the restart with
run_to_idle drains the durable repository
commit-hook queue, recovering and running any hook the crash left
un-drained (at-least-once / idempotent). Registering the app’s hook
runners on the fresh app models a real app re-registering them on boot.
Sourcepub fn crash_and_restart(&mut self, app: TestApp) -> &TestClient
pub fn crash_and_restart(&mut self, app: TestApp) -> &TestClient
Sourcepub fn mount_replica(
&mut self,
replica: impl Into<Replica>,
app: TestApp,
) -> &TestClient
pub fn mount_replica( &mut self, replica: impl Into<Replica>, app: TestApp, ) -> &TestClient
Mount app as the replica replica, next to the other replicas
(issue #3067).
Each replica is its own app on the sim’s one clock: its own state, job
runtime and scheduled tasks. It reads its own Replica clock. Give
each replica its own pool on one database, so they share data as a
fleet does:
let substrate = SqliteSubstrate::new()?;
for name in ["a", "b"] {
let pool = substrate.replica_pool(&sim.db_link(name))?;
sim.mount_replica(name, TestApp::new().with_db(pool).jobs(jobs![work]));
}
sim.run_for(Duration::from_secs(30)).await;With net set, the replica is also a SimNet host under
its name, so http://b/ reaches the replica b.
Process-wide state is not per replica: the cache, the event bus and the
global job client belong to the replica mounted last. Enqueue through a
replica’s own JobClient extension instead of job::enqueue.
§Panics
Panics if a replica with this name is already mounted. A name that
is the same host name, such as one that differs only in case, is the
same name. Use
restart_replica to mount it again.
Sourcepub fn restart_replica(&mut self, name: &str, app: TestApp) -> &TestClient
pub fn restart_replica(&mut self, name: &str, app: TestApp) -> &TestClient
Kill the replica name if it is alive, then mount app in its place.
The replica keeps its clock, as a restarted process keeps its host’s
clock. Rebuild app on the same database to recover its rows.
§Panics
Panics if no replica with this name was mounted.
Sourcepub fn kill_replica(&mut self, name: &str)
pub fn kill_replica(&mut self, name: &str)
Kill the replica name: stop its tasks and drop its app, as a process
crash does. A job handler that was running stops at its next await and
does not settle its claim. The database keeps every committed row. A
kill of a dead replica changes nothing.
§Panics
Panics if no replica with this name was mounted.
Sourcepub fn replica(&self, name: &str) -> &TestClient
pub fn replica(&self, name: &str) -> &TestClient
Sourcepub fn try_replica(&self, name: &str) -> Option<&TestClient>
pub fn try_replica(&self, name: &str) -> Option<&TestClient>
The client of the live replica name, or None.
Sourcepub fn replica_names(&self) -> Vec<&str>
pub fn replica_names(&self) -> Vec<&str>
The names of the live replicas, in mount order.
Sourcepub fn replica_clock(&self, name: &str) -> Option<ReplicaClock>
pub fn replica_clock(&self, name: &str) -> Option<ReplicaClock>
The clock settings of the replica name (alive or killed), or None.
Sourcepub fn step_replica_clock(&self, name: &str, by: TimeDelta)
pub fn step_replica_clock(&self, name: &str, by: TimeDelta)
Jump the wall clock of the replica name by by, as an NTP step does.
by can be negative: a step can go back. The monotonic clock does not
move. Timers the replica already set do not move.
§Panics
Panics if no replica with this name was mounted.
Sourcepub async fn run_for(&self, duration: Duration)
pub async fn run_for(&self, duration: Duration)
Let duration of virtual time pass, one event at a time (issue #3067).
The sim sleeps. Tokio moves its paused clock to the next timer only
when all tasks wait and no blocking work is queued, such as a SQLite
query. So database work ends before time moves on, and a seed replays
the same order. With replicas on SQLite, use it, not
advance.
Replica clocks move with each step. The clock of the app from
build moves once, at the end.
Sourcepub async fn interleave<F: Future>(&self, ops: Vec<F>) -> Vec<F::Output>
pub async fn interleave<F: Future>(&self, ops: Vec<F>) -> Vec<F::Output>
Run ops concurrently and poll them in a seeded order (issue #2967).
Each round polls the pending ops in an order drawn from the seed, and can hold one back for a round. So ops that share state (a lock, a row, a counter) meet in a different order per seed, and the same seed replays the same order. Outputs keep the input order.
let client = sim.client();
let ops = vec![client.post("/a").send(), client.post("/b").send()];
let responses = sim.interleave(ops).await;Sourcepub fn spawn<F>(&self, op: F) -> JoinHandle<F::Output> ⓘ
pub fn spawn<F>(&self, op: F) -> JoinHandle<F::Output> ⓘ
Spawn op on the sim runtime with seeded yields (issue #2967).
Before a poll, the task can yield from the seeded stream, which moves it behind the other ready tasks. Tasks spawned this way therefore run in a seed-driven order. Tasks the framework spawns keep tokio’s order.
Sourcepub fn crash_schedule(&self) -> CrashSchedule
pub fn crash_schedule(&self) -> CrashSchedule
The seed-derived CrashSchedule for this simulation.
A pure function of the seed: two same-seed sims return an
equal schedule. Pass a point’s CrashPoint::await_index to
crash_at to crash there.
Sourcepub fn crash_point(&self) -> Option<CrashPoint>
pub fn crash_point(&self) -> Option<CrashPoint>
The first entry of the seed-derived
crash_schedule.
None only if the schedule is empty (it never is under the default
length). Deterministic for a given seed.
Sourcepub fn client(&self) -> &TestClient
pub fn client(&self) -> &TestClient
Borrow the crate::test::TestClient mounted by build.
§Panics
Panics if build has not been called yet.
Sourcepub const fn try_client(&self) -> Option<&TestClient>
pub const fn try_client(&self) -> Option<&TestClient>
Borrow the mounted crate::test::TestClient, or None before
build.
Sourcepub fn strict_wall_clock(&mut self) -> &mut Self
pub fn strict_wall_clock(&mut self) -> &mut Self
Enable the real-time leak guard (strict_wall_clock) with the
default budget, panicking if a paused-sim step burns more than that much
real wall-clock time.
§What this guards (and what it deliberately does not)
A paused sim runs on tokio’s virtual timer: a
tokio::time::sleep / job backoff / delayed
enqueue consumes zero real time and only advances when
advance steps the clock. The one thing that breaks that
invariant is code that escapes the virtual timer and blocks the real
thread — a std::thread::sleep, a spawn_blocking, or a blocking
syscall. This guard catches the observable consequence of that: real
wall-clock time leaking into a step that should have taken virtually none.
It is not off-seam-read detection. It cannot tell you that some code
read Utc::now() / Instant::now() directly instead of through the
injected clock — a free-function now() call has no runtime interception
point in safe Rust, so its absence is not observable at runtime. Finding
those reads is a static-analysis (deny-lint) job; this guard is the
complementary runtime backstop for the worst pattern (a real blocking
sleep). Enabling it does not slow a legitimate virtual advance: jumping a
day of virtual time still costs microseconds of real time, well under
budget.
§Budget & the AUTUMN_SIM_STRICT_WALL_CLOCK_BUDGET_MS override
The default budget is deliberately generous (2000 ms) so ordinary CI
scheduling jitter never trips it — the target is a real sleep (seconds),
not sub-millisecond noise. Set the environment variable
AUTUMN_SIM_STRICT_WALL_CLOCK_BUDGET_MS (whole milliseconds) to override
the budget globally for a run; a blank or unparseable value is ignored and
the default (or the value passed to
strict_wall_clock_budget) applies. This
mirrors the AUTUMN_SIM_SEED idiom, so a too-tight budget on a slow
runner can be loosened without editing test code.
The guard is read-only during the run: enable it (chainably) before the
first advance / run_to_idle.
let mut sim = Sim::from_seed(0);
sim.strict_wall_clock();
sim.build(TestApp::new());
sim.advance(std::time::Duration::from_secs(24 * 3600)).await; // virtual, cheap
sim.run_to_idle().await;Sourcepub fn strict_wall_clock_budget(&mut self, budget: Duration) -> &mut Self
pub fn strict_wall_clock_budget(&mut self, budget: Duration) -> &mut Self
Enable the real-time leak guard with an explicit budget.
Identical to strict_wall_clock but starts from
budget instead of the 100 ms default. The
AUTUMN_SIM_STRICT_WALL_CLOCK_BUDGET_MS environment variable still
overrides budget when it holds a valid whole-millisecond value (so CI
can loosen the guard globally); a blank/unparseable value leaves budget
in effect. See strict_wall_clock for what the
guard does and does not catch.
let mut sim = Sim::from_seed(0);
sim.strict_wall_clock_budget(std::time::Duration::from_millis(5));Sourcepub async fn advance(&self, duration: Duration)
pub async fn advance(&self, duration: Duration)
Advance virtual time by duration, stepping the injected wall clock and
tokio’s paused timer wheel together.
The framework crate::time::Clock extractor (backed by the
simulation’s virtual clock) and tokio’s virtual timer (tokio::time::sleep,
job backoff delays, delayed enqueues) move by exactly the same amount, so
Utc::now()-via-extractor and a sleeping task stay in lockstep — a job
whose retry backs off 24 hours fires the instant this advances 24 hours,
with zero wall-clock delay. Timers that come due within the window fire
and their tasks are polled before this returns.
Pair with run_to_idle to then drain the work the
fired timers enqueued.
Sourcepub fn advance_to<Tz>(
&self,
target: &DateTime<Tz>,
) -> impl Future<Output = ()> + '_where
Tz: TimeZone,
pub fn advance_to<Tz>(
&self,
target: &DateTime<Tz>,
) -> impl Future<Output = ()> + '_where
Tz: TimeZone,
Advance virtual time to a specific zoned instant, resolving the timezone (including any DST transition) to the correct UTC instant and then stepping forward by the delta from the current sim instant.
This is the timezone/DST-aware companion to advance:
where advance takes a raw std::time::Duration, advance_to takes a
wall-clock target in any timezone and computes the real (UTC) delta for
you. It is generic over any chrono::TimeZone — pass a
chrono::DateTime<Utc>, a chrono::DateTime<chrono::FixedOffset>, or a
chrono::DateTime<chrono_tz::Tz> from the chrono-tz crate — so a caller
can express a zoned target without this crate hard-depending on any
particular timezone database.
The target is converted to UTC via chrono::DateTime::with_timezone,
which is unambiguous (every zoned DateTime already names a single
instant), and the sim then reuses advance internally so
the injected wall clock and tokio’s paused timer wheel stay in exact
lockstep — any tokio::time::sleep / job-backoff timer whose deadline
falls inside the crossed wall-clock window (a DST “spring-forward” gap
included) fires during the advance, then its task is polled before this
returns. Because the injected clock is UTC and monotonic, a spring-forward
boundary is just a shorter real interval — the timers inside it still fire
correctly.
§Forward-only semantics
Virtual time never moves backward:
- Target equals the current sim instant → this is a no-op (no clock/timer step at all).
- Target is strictly before the current sim instant → this panics with a clear message. Silently doing nothing would hide a test bug (a target computed to be in the past almost always means the test’s arithmetic is wrong), so the panic is deliberate.
Pair with run_to_idle afterward to drain the work
the fired timers enqueued.
§Panics
Panics if target resolves to a UTC instant strictly before the current
sim instant (see Forward-only semantics).
use chrono::{TimeZone, Utc};
// Advance the sim clock to a specific UTC instant.
let target = Utc.with_ymd_and_hms(2020, 3, 8, 12, 0, 0).unwrap();
sim.advance_to(&target).await;
sim.run_to_idle().await;Written as a non-async fn returning a future so the generic zoned
target is resolved to UTC synchronously and never captured across an
.await — the returned future holds only &self and the resolved
DateTime<Utc>, so it stays Send for any Tz (a borrowed or non-Sync
Tz would otherwise poison the future).
Sourcepub fn advance_to_local<Tz>(
&self,
local: NaiveDateTime,
tz: &Tz,
) -> impl Future<Output = ()> + '_where
Tz: TimeZone,
pub fn advance_to_local<Tz>(
&self,
local: NaiveDateTime,
tz: &Tz,
) -> impl Future<Output = ()> + '_where
Tz: TimeZone,
Advance virtual time to a naive local wall-clock time interpreted in
timezone tz, resolving DST edge cases explicitly (no .unwrap() on a
chrono::LocalResult).
Convenience wrapper over advance_to for the common
“advance to 2:30 AM local on this date” shape, where the naive local time
must be mapped to a single UTC instant. tz is any
chrono::TimeZone (e.g. a chrono_tz::Tz); the forward-only /
panic-on-past semantics of advance_to apply once the
instant is resolved.
§DST resolution (deterministic)
A naive local time need not correspond to exactly one UTC instant:
- Unambiguous (
LocalResult::Single) → that instant. - Fall-back / ambiguous (
LocalResult::Ambiguous, the wall time occurs twice as the clock rolls back) → the earlier of the two UTC instants. - Spring-forward gap (
LocalResult::None, the wall time never occurs because the clock jumps forward) → the nonexistent wall time is carried forward across the gap to a single deterministic post-transition instant (it is resolved by looking up the zone’s offset at the matching UTC-clock reading and applying it, which shifts the requested time past the boundary rather than erroring). For example a request for the nonexistent02:30on a US spring-forward day resolves to03:30local (the same instant, one gap-length later).
§Panics
Panics if the resolved instant is strictly before the current sim instant
(see advance_to).
use chrono::NaiveDate;
let local = NaiveDate::from_ymd_opt(2020, 3, 8).unwrap()
.and_hms_opt(3, 30, 0).unwrap();
sim.advance_to_local(local, &chrono_tz::America::New_York).await;Like advance_to, this is a non-async fn returning a
future: the &tz reference is used only while resolving the instant
synchronously and is not captured by the returned future, so the
future stays Send even though Tz need not be Sync.
Sourcepub async fn run_to_idle(&self)
pub async fn run_to_idle(&self)
Drain all ready work — enqueued jobs the in-process runtime can run now, plus tasks woken by timers that have already come due — until the runtime is quiescent.
The sim runtime is a single-threaded, current-thread runtime with the
clock paused, so background tasks (the job worker consuming its queue, a
retry timer that just fired, a delayed enqueue delivering) make progress
only when the running task yields. This cooperatively yields for
MAX_DRAIN_STEPS rounds.
It does not fast-forward to a future timer — advancing the clock to
reach a not-yet-due backoff/sleep is advance’s job
(tokio exposes no next-deadline hook, and a blind auto-advance would
break the clock lockstep). The idiom is therefore
advance to the next interesting instant, then
run_to_idle to settle the work it released.
§Panics
Panics with the seed when the drain does not settle: work still ran in
its last rounds (issue #2967). A job that enqueues itself again is the
usual cause. Use try_run_to_idle to get the
SimStall instead.
Sourcepub async fn try_run_to_idle(&self) -> Result<(), SimStall>
pub async fn try_run_to_idle(&self) -> Result<(), SimStall>
Like run_to_idle, but returns the stall.
§Errors
Returns SimStall when the drain never sees 64 quiet rounds in a row
within 2048 rounds. A round is quiet when no job starts, no scheduled
tick fires, no commit hook or outbox message drains and the task count
does not change.
A single long-running job, or a task that loops without spawning,
does not count as work.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for Sim
impl !RefUnwindSafe for Sim
impl !UnwindSafe for Sim
impl Send for Sim
impl Sync for Sim
impl Unpin for Sim
impl UnsafeUnpin for Sim
Blanket Implementations§
Source§impl<T> AggregateExpressionMethods for T
impl<T> AggregateExpressionMethods for T
Source§fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
DISTINCT modifier for aggregate functions Read moreSource§fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
ALL modifier for aggregate functions Read moreSource§fn aggregate_filter<P>(self, f: P) -> Self::Output
fn aggregate_filter<P>(self, f: P) -> Self::Output
Source§fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> AutumnCounterCaches for Twhere
T: 'static,
impl<T> AutumnCounterCaches for Twhere
T: 'static,
Source§const HAS_COUNTER_CACHES: bool = false
const HAS_COUNTER_CACHES: bool = false
Source§fn counter_caches() -> &'static [CounterCacheSpec<Self>]
fn counter_caches() -> &'static [CounterCacheSpec<Self>]
Source§impl<T> AutumnDependents for Twhere
T: ?Sized,
impl<T> AutumnDependents for Twhere
T: ?Sized,
Source§fn dependents() -> &'static [RuntimeDependentSpec]
fn dependents() -> &'static [RuntimeDependentSpec]
#[model] overrides via an inherent shadow when dependents exist.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>, which can then be
downcast into Box<dyn 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>, which 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> 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> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for 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> IntoSql for T
impl<T> IntoSql for T
Source§fn into_sql<T>(self) -> Self::Expression
fn into_sql<T>(self) -> Self::Expression
self to an expression for Diesel’s query builder. Read moreSource§fn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expression
fn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expression
&self to an expression for Diesel’s query builder. Read moreSource§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, Conn> RunQueryDsl<Conn> for T
impl<T, Conn> RunQueryDsl<Conn> for T
Source§fn execute<'conn, 'query>(
self,
conn: &'conn mut Conn,
) -> <Conn as AsyncConnectionCore>::ExecuteFuture<'conn, 'query>
fn execute<'conn, 'query>( self, conn: &'conn mut Conn, ) -> <Conn as AsyncConnectionCore>::ExecuteFuture<'conn, 'query>
Source§fn load<'query, 'conn, U>(
self,
conn: &'conn mut Conn,
) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
fn load<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
Source§fn load_stream<'conn, 'query, U>(
self,
conn: &'conn mut Conn,
) -> Self::LoadFuture<'conn>where
Conn: AsyncConnectionCore,
U: 'conn,
Self: LoadQuery<'query, Conn, U> + 'query,
fn load_stream<'conn, 'query, U>(
self,
conn: &'conn mut Conn,
) -> Self::LoadFuture<'conn>where
Conn: AsyncConnectionCore,
U: 'conn,
Self: LoadQuery<'query, Conn, U> + 'query,
Stream] with the returned rows. Read moreSource§fn get_result<'query, 'conn, U>(
self,
conn: &'conn mut Conn,
) -> AndThen<Self::LoadFuture<'conn>, LoadNext<Pin<Box<Self::Stream<'conn>>>>>
fn get_result<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, LoadNext<Pin<Box<Self::Stream<'conn>>>>>
Source§fn get_results<'query, 'conn, U>(
self,
conn: &'conn mut Conn,
) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
fn get_results<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
Vec with the affected rows. Read moreSource§impl<T> Scoped for T
impl<T> Scoped for T
Source§fn scope(ctx: &PolicyContext) -> ScopeQuery<'_, Self>
fn scope(ctx: &PolicyContext) -> ScopeQuery<'_, Self>
ScopeQuery for this type. Resolves the
registered scope at .load() time, not here.