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§
Sourcefn auditable_type() -> &'static strwhere
Self: Sized,
fn auditable_type() -> &'static strwhere
Self: Sized,
The polymorphic type name stored in auditable_type, e.g. "Post".
Sourcefn auditable_id(&self) -> AuditId
fn auditable_id(&self) -> AuditId
This record’s id.
Sourcefn audited_attributes(&self) -> ValueMap
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.
Sourcefn audit_options() -> AuditOptionswhere
Self: Sized,
fn audit_options() -> AuditOptionswhere
Self: Sized,
The per-model options controlling how this type is audited.
Provided Methods§
Sourcefn primary_key() -> &'static strwhere
Self: Sized,
fn primary_key() -> &'static strwhere
Self: Sized,
The primary-key column name (default "id"), excluded from audits by default.
Sourcefn inheritance_column() -> Option<&'static str>where
Self: Sized,
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.
Sourcefn audit_associated(&self) -> Option<(String, AuditId)>
fn audit_associated(&self) -> Option<(String, AuditId)>
The polymorphic associated/parent record (type, id) to record on each audit. Default:
none.
Sourcefn audit_if(&self) -> bool
fn audit_if(&self) -> bool
Instance condition: audit only when this returns true. Default true.
Sourcefn audit_unless(&self) -> bool
fn audit_unless(&self) -> bool
Instance condition: skip auditing when this returns true. Default
false.
Sourceasync fn audited_create(&self, backend: &dyn Backend) -> Result<Option<Audit>>where
Self: Sized,
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.
Sourceasync fn audited_create_with_comment(
&self,
backend: &dyn Backend,
comment: impl Into<String> + Send,
) -> 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,
Auditable::audited_create with an audit comment.
Sourceasync fn audited_update(
&self,
backend: &dyn Backend,
old: &Self,
) -> Result<Option<Audit>>where
Self: Sized,
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.
Sourceasync 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_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.
Sourceasync fn audited_destroy(&self, backend: &dyn Backend) -> Result<Option<Audit>>where
Self: Sized,
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.
Sourceasync fn audited_destroy_with_comment(
&self,
backend: &dyn Backend,
comment: impl Into<String> + Send,
) -> 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,
Auditable::audited_destroy with an audit comment.
Sourceasync fn audits(
backend: &dyn Backend,
id: impl Into<AuditId> + Send,
) -> Result<Vec<Audit>>where
Self: Sized,
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.
Sourcefn query(backend: &dyn Backend, id: impl Into<AuditId>) -> AuditQueryBuilder<'_>where
Self: Sized,
fn query(backend: &dyn Backend, id: impl Into<AuditId>) -> AuditQueryBuilder<'_>where
Self: Sized,
Start a scoped query (.creates(), .updates(), .from_version(..), .descending(), …).
Sourcefn associated_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,
Start a scoped query over the audits associated with this record (see
Auditable::associated_audits).
Sourceasync fn associated_audits(
backend: &dyn Backend,
id: impl Into<AuditId> + Send,
) -> Result<Vec<Audit>>where
Self: Sized,
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.
Sourceasync fn own_and_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,
Union of this record’s own audits and its associated audits, ordered by created_at
descending.
Sourceasync fn revisions(
backend: &dyn Backend,
id: impl Into<AuditId> + Send,
) -> Result<Vec<Revision>>where
Self: Sized,
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.
Sourceasync fn revisions_from(
backend: &dyn Backend,
id: impl Into<AuditId> + Send,
from_version: i32,
) -> 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,
All revisions at/after from_version.
Sourceasync fn revision(
backend: &dyn Backend,
id: impl Into<AuditId> + Send,
version: i32,
) -> Result<Option<Revision>>where
Self: Sized,
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.
Sourceasync fn revision_previous(
backend: &dyn Backend,
id: impl Into<AuditId> + Send,
) -> Result<Option<Revision>>where
Self: Sized,
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.
Sourceasync fn revision_at(
backend: &dyn Backend,
id: impl Into<AuditId> + Send,
time: DateTime<Utc>,
) -> 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,
The latest revision at/before time, or None if time precedes all audits.
Sourcefn disable_auditing()where
Self: Sized,
fn disable_auditing()where
Self: Sized,
Persistently disable auditing for this type.
Sourcefn enable_auditing()where
Self: Sized,
fn enable_auditing()where
Self: Sized,
Persistently re-enable auditing for this type.
Sourcefn auditing_enabled() -> boolwhere
Self: Sized,
fn auditing_enabled() -> boolwhere
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".