pub trait ProfileEditor:
Send
+ Sync
+ 'static {
type Input: FormInput;
type User: PanelUser;
// Required methods
fn fill(&self, cx: &Cx, user: &Self::User) -> Self::Input;
fn save(
&self,
cx: &Cx,
user: &Self::User,
input: Self::Input,
ex: &mut dyn Executor,
) -> impl Future<Output = Result<ProfileUpdate>> + Send;
// Provided method
fn validate(
&self,
_cx: &Cx,
_user: &Self::User,
_input: &Self::Input,
_ex: &mut dyn Executor,
) -> impl Future<Output = Result<FieldErrors>> + Send { ... }
}Expand description
How a panel lets the signed-in user edit their own account on its profile page, installed
with Auth::profile.
It mirrors a Registrar: Input is the form the page
shows, fill seeds it from the account, validate refuses a
submission field by field, and save writes it. validate and save run in one
transaction the framework opens.
The shipped PasswordAuth edits an AdminUser
through a Profile; an app with its own user table implements it beside its
Authenticator, for the same user type:
#[derive(tablo_core::FormInput)]
struct Rename {
name: String,
}
struct StaffProfile;
impl ProfileEditor for StaffProfile {
type Input = Rename;
type User = Staff;
fn fill(&self, _cx: &Cx, staff: &Staff) -> Rename {
Rename {
name: staff.name.clone(),
}
}
async fn save(
&self,
_cx: &Cx,
staff: &Staff,
rename: Rename,
ex: &mut dyn toasty::Executor,
) -> topcoat::Result<ProfileUpdate> {
Staff::filter(Staff::fields().id().eq(staff.id))
.update()
.name(rename.name)
.exec(ex)
.await?;
Ok(ProfileUpdate::Details)
}
}Required Associated Types§
Sourcetype Input: FormInput
type Input: FormInput
What the profile page asks for: Profile, or the app’s own
#[derive(FormInput)] struct.
Sourcetype User: PanelUser
type User: PanelUser
The account the page edits: the type the panel’s Authenticator
loads, which mounting checks.
Required Methods§
Provided Methods§
Sourcefn validate(
&self,
_cx: &Cx,
_user: &Self::User,
_input: &Self::Input,
_ex: &mut dyn Executor,
) -> impl Future<Output = Result<FieldErrors>> + Send
fn validate( &self, _cx: &Cx, _user: &Self::User, _input: &Self::Input, _ex: &mut dyn Executor, ) -> impl Future<Output = Result<FieldErrors>> + Send
Refuse a submission save should not receive, such as a wrong current
password: each error names an input field’s key and renders under its control. Defaults
to none. A key no control renders is a declaration error: the page would show no message.
It runs inside the save’s transaction ex, after the input parses and its controls’ own
rules pass.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".
Implementors§
Source§impl ProfileEditor for PasswordAuth
Edits the signed-in AdminUser’s name, email and password through a Profile. Changing
the email or the password asks for the current password, and refuses a new password
new_password_errors refuses and, once the current password
verifies, an email another account holds. A changed password is a
ProfileUpdate::Credentials. A new email goes through request_email_change: on a panel
with Auth::email_verification it waits for its link,
elsewhere it is stored at once, as a credential change. Install it with
Auth::profile.
impl ProfileEditor for PasswordAuth
Edits the signed-in AdminUser’s name, email and password through a Profile. Changing
the email or the password asks for the current password, and refuses a new password
new_password_errors refuses and, once the current password
verifies, an email another account holds. A changed password is a
ProfileUpdate::Credentials. A new email goes through request_email_change: on a panel
with Auth::email_verification it waits for its link,
elsewhere it is stored at once, as a credential change. Install it with
Auth::profile.