Skip to main content

Ability

Enum Ability 

Source
pub enum Ability<'a, M> {
Show 13 variants ViewAny, View(&'a M), Create, Update(&'a M), DeleteAny, Delete(&'a M), RestoreAny, Restore(&'a M), ForceDeleteAny, ForceDelete(&'a M), RunAny { action: &'static str, }, Run { action: &'static str, record: &'a M, }, RunHeader { action: &'static str, },
}
Expand description

One thing a policy is asked to allow; record abilities are asked once per loaded row, and a record that cannot be viewed cannot be written by guessing its key.

Variants§

§

ViewAny

Read the resource’s rows: asked by the list and its live refresh, the sidebar entry, the export, related tables, relationship options and relation columns, and the global search. All but the global search show every row of the resource’s query, asking no record ability of it: a policy cannot run in the database, so the rows a user must not see belong out of ResourceDef::query.

§

View(&'a M)

Open one record: asked by the detail page, the edit page and POST, deletes, record pages and each global search result, which leaves out a record it refuses. Every write asks it of the records it loads, and a list row it refuses shows without its actions or checkbox.

§

Create

Open the create form and submit it: asked by the create page and POST, and the Create button.

§

Update(&'a M)

Edit one record: asked by the edit page and POST, and the row’s Edit action.

§

DeleteAny

Delete at all: asked by the delete and bulk-delete POSTs before any record loads, the Delete action and the bulk column.

§

Delete(&'a M)

Delete one record: asked of each record a delete removes, and by the row’s Delete action and checkbox.

§

RestoreAny

Restore trashed records at all, on a resource that soft-deletes: asked by the restore POSTs and the Restore buttons.

§

Restore(&'a M)

Restore one trashed record: asked of each record a restore brings back, and by its Restore button and checkbox.

§

ForceDeleteAny

Delete trashed records for good at all, on a resource that soft-deletes. Allowed only with DeleteAny. Asked by the force-delete POSTs and the Delete permanently buttons.

§

ForceDelete(&'a M)

Delete one trashed record for good. Allowed only with Delete of it, so a policy refusing a record’s delete refuses its force delete too. Asked of each trashed record a force delete removes, and by its button and checkbox.

§

RunAny

Run the custom Action whose NAME is action at all, before Run is asked of each record: asked by the action’s POSTs, before any record loads, its buttons, and the bulk column for a bulk action.

Fields

§action: &'static str

The action’s NAME.

§

Run

Run the custom Action whose NAME is action on one record: asked of each record the action runs on, and by its button on the record’s row and pages and, for a bulk action, the record’s checkbox.

Fields

§action: &'static str

The action’s NAME.

§record: &'a M

The record it runs on.

§

RunHeader

Run the HeaderAction whose NAME is action from the list’s header. It acts on no record, so nothing else of the policy is asked but ViewAny.

It is not RunAny: a policy that grants every record action with RunAny { .. } => true grants no header action by it.

Fields

§action: &'static str

The action’s NAME.

Implementations§

Source§

impl<'a, M> Ability<'a, M>

Source

pub fn record(self) -> Option<&'a M>

The record the ability names, if any.

Source

pub fn is_read(self) -> bool

Whether the ability only reads.

Source

pub fn written_record(self) -> Option<&'a M>

The record the ability writes: an update, a delete, a restore, a force delete or a record action’s run on it. None for a read and for an ability over no existing record: Create, the _any abilities and RunHeader.

A policy refusing every write to some records reads it, and so also refuses the record actions and soft-delete writes a resource gains later. A header action writes no record it is handed, so such a policy allows it unless it matches RunHeader too:

fn keep_root(_cx: &Cx, ability: Ability<'_, User>) -> bool {
    ability
        .written_record()
        .is_none_or(|user| user.name != "root")
}
Source§

impl<M> Ability<'_, M>

Source

pub fn is_action<A, R>(self) -> bool
where A: Action<R>, R: Resource<Model = M>,

Whether the ability is RunAny or Run for the action A.

It compares against A::NAME, so renaming the action keeps the policy matching it, and a type that is not an action of the resource does not compile. R is inferred when A is an action of one resource.

fn post_policy(cx: &Cx, ability: Ability<'_, Post>) -> bool {
    match ability {
        Ability::Run { record, .. } if ability.is_action::<Publish, _>() => !record.published,
        Ability::ViewAny | Ability::View(_) => true,
        _ => is_editor(cx),
    }
}
Source§

impl<M> Ability<'_, M>

Source

pub fn is_header_action<A: HeaderAction>(self) -> bool

Whether the ability is RunHeader for the header action A, which a resource’s policy answers to let the request run it.

fn post_policy(cx: &Cx, ability: Ability<'_, Post>) -> bool {
    match ability {
        _ if ability.is_header_action::<RecountTags>() => is_admin(cx),
        Ability::ViewAny | Ability::View(_) => true,
        _ => false,
    }
}

Trait Implementations§

Source§

impl<'a, M> Clone for Ability<'a, M>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a, M> Copy for Ability<'a, M>

Source§

impl<'a, M: Debug> Debug for Ability<'a, M>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a, M> Forget for Ability<'a, M>

§

impl<'a, M> Freeze for Ability<'a, M>
where &'a M: Freeze,

§

impl<'a, M> Move for Ability<'a, M>

§

impl<'a, M> RefUnwindSafe for Ability<'a, M>

§

impl<'a, M> Send for Ability<'a, M>
where &'a M: Send,

§

impl<'a, M> Sync for Ability<'a, M>
where &'a M: Sync,

§

impl<'a, M> Unpin for Ability<'a, M>
where &'a M: Unpin,

§

impl<'a, M> UnsafeUnpin for Ability<'a, M>

§

impl<'a, M> UnwindSafe for Ability<'a, M>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more