pub struct ValidationReport {
pub collisions: Vec<PermissionCollision>,
}Expand description
Validation outcome for a set of permission strings.
Produced by:
§Terminology
- Duplicate permission: The exact same string appears more than once. These are represented internally as a “collision” where every entry in the collision group is identical.
- Hash collision: Two different normalized permission strings that deterministically hash (via the 64‑bit truncated SHA‑256) to the same ID. This is extremely unlikely and should be treated as a critical configuration problem if it ever occurs.
§Interpreting Results
ValidationReport::is_validistruewhen there are no collisions at all (neither duplicates nor distinct-string collisions).ValidationReport::duplicatesreturns only pure duplicates (all strings in the collision set are identical).- Distinct collisions (same hash, different strings) are considered more severe and
will appear in log output /
detailed_errorsbut not induplicates().
§Typical Actions
| Situation | Action | Severity |
|---|---|---|
| Report is valid | Proceed with startup / reload | None |
| One or more duplicates only | Remove redundant entries (usually a config hygiene issue) | Low / Medium |
| Any non‑duplicate hash collision detected | Rename at least one colliding permission (treat as urgent) | High (very rare) |
§Convenience Methods
summarygives a compact human‑readable description (good for logs / errors).detailed_errorsenumerates each issue (useful for API / CLI feedback).total_issuescounts total collision groups (duplicates + distinct collisions).
§Example
use axum_gate::permissions::{PermissionCollisionChecker, ApplicationValidator};
// Direct checker
let mut checker = PermissionCollisionChecker::new(vec![
"user:read".into(),
"user:read".into(), // duplicate
"admin:full".into(),
]);
let report = checker.validate().unwrap();
assert!(!report.is_valid());
assert_eq!(report.duplicates(), vec!["user:read".to_string()]);
// Builder style
let report2 = ApplicationValidator::new()
.add_permissions(["user:read", "user:read"])
.validate()
.unwrap();
assert!(!report2.is_valid());§Performance Notes
The validator groups by 64‑bit IDs first; memory usage is proportional to the number of distinct permission IDs plus total string storage. For typical application-scale permission sets (≪10k) this is negligible.
§Logging
Use log_results for structured tracing output. Successful validation logs
at INFO, issues at WARN.
Fields§
§collisions: Vec<PermissionCollision>All collision groups (duplicates and true hash collisions).
Each entry contains:
- The 64‑bit permission ID (
id) - The list of original permission strings that map to that ID
Invariants:
- Length >= 2 for each
permissionsvector - A “duplicate” group has every element string-equal
- A “distinct collision” group has at least one differing string
Implementations§
Source§impl ValidationReport
impl ValidationReport
Sourcepub fn is_valid(&self) -> bool
pub fn is_valid(&self) -> bool
Returns true if validation passed without any issues.
A validation is considered successful if there are no hash collisions.
Sourcepub fn duplicates(&self) -> Vec<String>
pub fn duplicates(&self) -> Vec<String>
Returns duplicate permission strings found.
Duplicates are derived from collisions where all permissions are identical.
Sourcepub fn summary(&self) -> String
pub fn summary(&self) -> String
Returns a human-readable summary of validation results.
For successful validations, returns a success message. For failed validations, provides details about what issues were found.
Sourcepub fn log_results(&self)
pub fn log_results(&self)
Logs validation results using the tracing crate.
This method will log at INFO level for successful validations and WARN level for any issues found.
Sourcepub fn detailed_errors(&self) -> Vec<String>
pub fn detailed_errors(&self) -> Vec<String>
Returns detailed information about all issues found.
This method provides comprehensive details suitable for debugging or detailed error reporting.
Sourcepub fn total_issues(&self) -> usize
pub fn total_issues(&self) -> usize
Returns the total number of issues found.
Trait Implementations§
Source§impl Debug for ValidationReport
impl Debug for ValidationReport
Source§impl Default for ValidationReport
impl Default for ValidationReport
Source§fn default() -> ValidationReport
fn default() -> ValidationReport
Auto Trait Implementations§
impl Freeze for ValidationReport
impl RefUnwindSafe for ValidationReport
impl Send for ValidationReport
impl Sync for ValidationReport
impl Unpin for ValidationReport
impl UnwindSafe for ValidationReport
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
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