Skip to main content

Auditable

Trait Auditable 

Source
pub trait Auditable: Send + Sync {
Show 28 methods // Required methods fn auditable_type() -> &'static str where Self: Sized; fn auditable_id(&self) -> AuditId; fn audited_attributes(&self) -> ValueMap; fn audit_options() -> AuditOptions where Self: Sized; // Provided methods fn primary_key() -> &'static str where Self: Sized { ... } fn inheritance_column() -> Option<&'static str> where Self: Sized { ... } fn audit_associated(&self) -> Option<(String, AuditId)> { ... } fn audit_if(&self) -> bool { ... } fn audit_unless(&self) -> bool { ... } async fn audited_create( &self, backend: &dyn Backend, ) -> Result<Option<Audit>> where Self: Sized { ... } async fn audited_create_with_comment( &self, backend: &dyn Backend, comment: impl Into<String> + Send, ) -> Result<Option<Audit>> where Self: Sized { ... } async fn audited_update( &self, backend: &dyn Backend, old: &Self, ) -> Result<Option<Audit>> where Self: Sized { ... } async fn audited_update_with_comment( &self, backend: &dyn Backend, old: &Self, comment: impl Into<String> + Send, ) -> Result<Option<Audit>> where Self: Sized { ... } async fn audited_destroy( &self, backend: &dyn Backend, ) -> Result<Option<Audit>> where Self: Sized { ... } async fn audited_destroy_with_comment( &self, backend: &dyn Backend, comment: impl Into<String> + Send, ) -> Result<Option<Audit>> where Self: Sized { ... } async fn audits( backend: &dyn Backend, id: impl Into<AuditId> + Send, ) -> Result<Vec<Audit>> where Self: Sized { ... } fn query( backend: &dyn Backend, id: impl Into<AuditId>, ) -> AuditQueryBuilder<'_> where Self: Sized { ... } fn associated_query( backend: &dyn Backend, id: impl Into<AuditId>, ) -> AuditQueryBuilder<'_> where Self: Sized { ... } async fn associated_audits( backend: &dyn Backend, id: impl Into<AuditId> + Send, ) -> Result<Vec<Audit>> where Self: Sized { ... } async fn own_and_associated_audits( backend: &dyn Backend, id: impl Into<AuditId> + Send, ) -> Result<Vec<Audit>> where Self: Sized { ... } async fn revisions( backend: &dyn Backend, id: impl Into<AuditId> + Send, ) -> Result<Vec<Revision>> where Self: Sized { ... } async fn revisions_from( backend: &dyn Backend, id: impl Into<AuditId> + Send, from_version: i32, ) -> Result<Vec<Revision>> where Self: Sized { ... } async fn revision( backend: &dyn Backend, id: impl Into<AuditId> + Send, version: i32, ) -> Result<Option<Revision>> where Self: Sized { ... } async fn revision_previous( backend: &dyn Backend, id: impl Into<AuditId> + Send, ) -> Result<Option<Revision>> where Self: Sized { ... } async fn revision_at( backend: &dyn Backend, id: impl Into<AuditId> + Send, time: DateTime<Utc>, ) -> Result<Option<Revision>> where Self: Sized { ... } fn disable_auditing() where Self: Sized { ... } fn enable_auditing() where Self: Sized { ... } fn auditing_enabled() -> bool where Self: Sized { ... }
}
Expand description

Make a model auditable.

Implement the four required items; everything else (writing audits, querying, scopes, revisions, enable/disable) is provided.

use auditlog::{Auditable, AuditOptions, AuditId, ValueMap};
use serde_json::json;

struct Post { id: i64, title: String, body: String }

impl Auditable for Post {
    fn auditable_type() -> &'static str { "Post" }
    fn auditable_id(&self) -> AuditId { self.id.into() }
    fn audited_attributes(&self) -> ValueMap {
        let mut m = ValueMap::new();
        m.insert("id".into(), json!(self.id));
        m.insert("title".into(), json!(self.title));
        m.insert("body".into(), json!(self.body));
        m
    }
    fn audit_options() -> AuditOptions {
        AuditOptions::builder().except(["body"]).build()
    }
}

The async writing/querying methods are where Self: Sized and take a &dyn Backend, so call them directly on your value: post.audited_create(&backend).await?.

Required Methods§

Source

fn auditable_type() -> &'static str
where Self: Sized,

The polymorphic type name stored in auditable_type, e.g. "Post".

Source

fn auditable_id(&self) -> AuditId

This record’s id.

Source

fn audited_attributes(&self) -> ValueMap

The full attribute map (all columns) as JSON values. Filtering by only/except and the default-ignored columns is applied by the crate, so return everything here. The integer vs label representation of enum columns is whatever you put in this map.

Source

fn audit_options() -> AuditOptions
where Self: Sized,

The per-model options controlling how this type is audited.

Provided Methods§

Source

fn primary_key() -> &'static str
where Self: Sized,

The primary-key column name (default "id"), excluded from audits by default.

Source

fn inheritance_column() -> Option<&'static str>
where Self: Sized,

The single-table-inheritance discriminator column (e.g. "type"), if your model uses STI. When set, it is excluded from audits by default. Default: none.

Source

fn audit_associated(&self) -> Option<(String, AuditId)>

The polymorphic associated/parent record (type, id) to record on each audit. Default: none.

Source

fn audit_if(&self) -> bool

Instance condition: audit only when this returns true. Default true.

Source

fn audit_unless(&self) -> bool

Instance condition: skip auditing when this returns true. Default false.

Source

async fn audited_create(&self, backend: &dyn Backend) -> Result<Option<Audit>>
where Self: Sized,

Record a create audit. Call after persisting the new record. Returns the written audit, or None if auditing was disabled / not configured for create.

Source

async fn audited_create_with_comment( &self, backend: &dyn Backend, comment: impl Into<String> + Send, ) -> Result<Option<Audit>>
where Self: Sized,

Auditable::audited_create with an audit comment.

Source

async fn audited_update( &self, backend: &dyn Backend, old: &Self, ) -> Result<Option<Audit>>
where Self: Sized,

Record an update audit, diffing old (the prior state) against self (the new state). Call before persisting the change if you want comment-required to be able to abort it.

Source

async fn audited_update_with_comment( &self, backend: &dyn Backend, old: &Self, comment: impl Into<String> + Send, ) -> Result<Option<Audit>>
where Self: Sized,

Auditable::audited_update with an audit comment. A comment alone (no attribute changes) still writes an audit unless update_with_comment_only(false) was set.

Source

async fn audited_destroy(&self, backend: &dyn Backend) -> Result<Option<Audit>>
where Self: Sized,

Record a destroy audit from the record’s current snapshot. Call before deleting.

Source

async fn audited_destroy_with_comment( &self, backend: &dyn Backend, comment: impl Into<String> + Send, ) -> Result<Option<Audit>>
where Self: Sized,

Auditable::audited_destroy with an audit comment.

Source

async fn audits( backend: &dyn Backend, id: impl Into<AuditId> + Send, ) -> Result<Vec<Audit>>
where Self: Sized,

All audits for the given record id, ordered by version ascending.

Source

fn query(backend: &dyn Backend, id: impl Into<AuditId>) -> AuditQueryBuilder<'_>
where Self: Sized,

Start a scoped query (.creates(), .updates(), .from_version(..), .descending(), …).

Source

fn associated_query( backend: &dyn Backend, id: impl Into<AuditId>, ) -> AuditQueryBuilder<'_>
where Self: Sized,

Start a scoped query over the audits associated with this record (see Auditable::associated_audits).

Source

async fn associated_audits( backend: &dyn Backend, id: impl Into<AuditId> + Send, ) -> Result<Vec<Audit>>
where Self: Sized,

Audits whose associated points at this record.

Source

async fn own_and_associated_audits( backend: &dyn Backend, id: impl Into<AuditId> + Send, ) -> Result<Vec<Audit>>
where Self: Sized,

Union of this record’s own audits and its associated audits, ordered by created_at descending.

Source

async fn revisions( backend: &dyn Backend, id: impl Into<AuditId> + Send, ) -> Result<Vec<Revision>>
where Self: Sized,

All revisions (one per audit), from version 1.

Source

async fn revisions_from( backend: &dyn Backend, id: impl Into<AuditId> + Send, from_version: i32, ) -> Result<Vec<Revision>>
where Self: Sized,

All revisions at/after from_version.

Source

async fn revision( backend: &dyn Backend, id: impl Into<AuditId> + Send, version: i32, ) -> Result<Option<Revision>>
where Self: Sized,

The revision at a specific version, or None if version exceeds the latest.

Source

async fn revision_previous( backend: &dyn Backend, id: impl Into<AuditId> + Send, ) -> Result<Option<Revision>>
where Self: Sized,

The previous revision (second-most-recent version), or None if there is no history.

Source

async fn revision_at( backend: &dyn Backend, id: impl Into<AuditId> + Send, time: DateTime<Utc>, ) -> Result<Option<Revision>>
where Self: Sized,

The latest revision at/before time, or None if time precedes all audits.

Source

fn disable_auditing()
where Self: Sized,

Persistently disable auditing for this type.

Source

fn enable_auditing()
where Self: Sized,

Persistently re-enable auditing for this type.

Source

fn auditing_enabled() -> bool
where Self: Sized,

Whether auditing is currently enabled for this type (global master switch AND the type’s persistent flag). Scope guards (without_auditing/with_auditing) are not reflected here since they are task-local.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§