pub struct AppState(/* private fields */);Expand description
Shared state available to every handler through State<AppState>.
One Arc around AppStateInner: every middleware layer, the request’s
extensions and each handler’s State clone it, so a clone is one atomic
increment (it was a struct of about 35 fields, cloned tens of times per
request: #334). Read its parts as fields, through Deref:
state.db, state.config, state.queue…
Implementations§
Source§impl AppState
impl AppState
Sourcepub fn broadcast(&self, event: &str, data: impl Serialize) -> Result
pub fn broadcast(&self, event: &str, data: impl Serialize) -> Result
Sends the DOM event event, with data as its detail, to every
page open in this process with a notification stream (the UI kit’s
notification_bell or event_stream(), which need
Auth::new().notifications()), whoever is logged in there.
Pages listen as to any DOM event on document: htmx with
hx-trigger="order-updated from:document", Alpine with
x-on:order-updated.document="…", a script with
document.addEventListener("order-updated", e => e.detail). The
event renox:toast with {"toasts": [toast]} shows toasts.
It is fire-and-forget: nothing is stored, and pages that aren’t
connected at that moment (closed, reconnecting, open on another
server, or a queue:work process sent it) never get it. Use a
database notification (AppState::notify) for what must arrive.
state.broadcast("order-updated", json!({ "id": 7, "status": "paid" }))?;
// Only Ana's pages (any tab, any device on this server):
state.broadcast_to(user.id, "renox:toast", json!({ "toasts": [Toast::info("Export ready")] }))?;Sourcepub fn broadcast_to(
&self,
user_id: i64,
event: &str,
data: impl Serialize,
) -> Result
pub fn broadcast_to( &self, user_id: i64, event: &str, data: impl Serialize, ) -> Result
AppState::broadcast to the pages of one user (by id) only.
Sourcepub async fn notify(
&self,
to: impl Into<Recipient>,
notification: &impl Notification,
) -> Result
pub async fn notify( &self, to: impl Into<Recipient>, notification: &impl Notification, ) -> Result
Delivers notification now to a user (&user) or to addresses (a
Recipient), on each of its channels. The database row is written
first and mail sent last, so a failure doesn’t leave a message behind
that a retry would send again.
Sourcepub async fn notify_later(
&self,
to: impl Into<Recipient>,
notification: &impl Notification,
) -> Result
pub async fn notify_later( &self, to: impl Into<Recipient>, notification: &impl Notification, ) -> Result
Like notify, but mail and the app’s channels are sent by queue
workers, each channel as its own job with its own retries. The
messages are built now; the database row is written now.
Source§impl AppState
impl AppState
Sourcepub fn lang(&self, locale: &str) -> Lang
pub fn lang(&self, locale: &str) -> Lang
The texts of locale, for code without a request (a job, a mail
to someone in another language).
Sourcepub fn current_lang(&self) -> Lang
pub fn current_lang(&self) -> Lang
The texts of the current_locale.
Source§impl AppState
impl AppState
Sourcepub fn mail_view(
&self,
to: impl Into<String>,
subject: impl Into<String>,
view: &str,
ctx: impl Serialize,
) -> Result<Mail>
pub fn mail_view( &self, to: impl Into<String>, subject: impl Into<String>, view: &str, ctx: impl Serialize, ) -> Result<Mail>
Renders {view}.html into a mail, with {view}.txt as the text
version when it exists (otherwise text made from the HTML).
Templates see app (app.locale too) and t(key, …) in the
current_locale besides ctx, can
extend renox/mail/layout.html and import
renox/mail/components.html (button, panel, table).
Sourcepub fn mail_view_in(
&self,
locale: &str,
to: impl Into<String>,
subject: impl Into<String>,
view: &str,
ctx: impl Serialize,
) -> Result<Mail>
pub fn mail_view_in( &self, locale: &str, to: impl Into<String>, subject: impl Into<String>, view: &str, ctx: impl Serialize, ) -> Result<Mail>
mail_view in locale (the recipient’s language).
Sourcepub async fn queue_mail(&self, mail: Mail) -> Result<i64>
pub async fn queue_mail(&self, mail: Mail) -> Result<i64>
Sends mail from a queue worker, retrying up to five times.
Sourcepub fn mailer_named(&self, name: &str) -> Result<&Mailer>
pub fn mailer_named(&self, name: &str) -> Result<&Mailer>
A mailer the app added with App::mailer, e.g.
state.mailer_named("newsletter")?.send(mail); an unknown name is an
error (500).
Source§impl AppState
impl AppState
Sourcepub fn signed_url(
&self,
name: &str,
params: &[&dyn Display],
ttl: Duration,
) -> Result<String>
pub fn signed_url( &self, name: &str, params: &[&dyn Display], ttl: Duration, ) -> Result<String>
An absolute URL to a named route, valid for ttl and signed with APP_KEY.
Source§impl AppState
impl AppState
Sourcepub fn url(&self, name: &str, params: &[&dyn Display]) -> Result<String>
pub fn url(&self, name: &str, params: &[&dyn Display]) -> Result<String>
The URL path of a named route, e.g. state.url("products.show", &[&id]).
Sourcepub fn encrypt(&self, plain: &str) -> String
pub fn encrypt(&self, plain: &str) -> String
Encrypts plain with APP_KEY (AES-256-GCM), e.g. an API secret a
user saves, before storing it. The result is base64 text; only
AppState::decrypt with the same key reads it back, and any change
to it is detected. Rotating APP_KEY makes old values unreadable.
let sealed = state.encrypt("sk_live_123");
assert_eq!(state.decrypt(&sealed)?, "sk_live_123");Trait Implementations§
Source§impl Deref for AppState
impl Deref for AppState
Source§type Target = AppStateInner
type Target = AppStateInner
Source§fn deref(&self) -> &AppStateInner
fn deref(&self) -> &AppStateInner
Source§impl<T> FromRequest<AppState> for Valid<T>
impl<T> FromRequest<AppState> for Valid<T>
Source§impl FromRequestParts<AppState> for Cookies
impl FromRequestParts<AppState> for Cookies
Auto Trait Implementations§
impl !RefUnwindSafe for AppState
impl !UnwindSafe for AppState
impl Freeze for AppState
impl Send for AppState
impl Sync for AppState
impl Unpin for AppState
impl UnsafeUnpin for AppState
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
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