use crate::errors_core::Result;
use crate::permissions::collision_checker::PermissionCollisionChecker;
use crate::permissions::errors::PermissionsError;
use crate::permissions::validation_report::ValidationReport;
use tracing::info;
pub struct ApplicationValidator {
permissions: Vec<String>,
}
impl ApplicationValidator {
pub fn new() -> Self {
Self {
permissions: Vec::new(),
}
}
pub fn add_permissions<I, S>(mut self, permissions: I) -> Self
where
I: IntoIterator<Item = S>,
S: Into<String>,
{
self.permissions
.extend(permissions.into_iter().map(|s| s.into()));
self
}
pub fn add_permission_strings(mut self, permissions: Vec<String>) -> Self {
self.permissions.extend(permissions);
self
}
pub fn add_permission<S: Into<String>>(mut self, permission: S) -> Self {
self.permissions.push(permission.into());
self
}
pub fn validate(self) -> Result<ValidationReport, PermissionsError> {
let mut checker = PermissionCollisionChecker::new(self.permissions);
let report = checker.validate().map_err(|e| {
PermissionsError::collision(
0,
vec![format!("Permission validation process failed: {}", e)],
)
})?;
report.log_results();
if report.is_valid() {
info!("✓ Permission validation completed successfully");
}
Ok(report)
}
pub fn permission_count(&self) -> usize {
self.permissions.len()
}
}
impl Default for ApplicationValidator {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn application_validator_basic() {
let result = ApplicationValidator::new()
.add_permissions(["user:read", "user:write"])
.add_permission("admin:delete")
.validate();
match result {
Ok(report) => assert!(report.is_valid()),
Err(error) => panic!("validation unexpectedly failed: {error}"),
}
}
#[test]
fn application_validator_with_duplicates() {
let result = ApplicationValidator::new()
.add_permissions(["user:read", "user:read"])
.validate();
match result {
Ok(report) => {
assert!(!report.is_valid());
assert!(!report.duplicates().is_empty());
}
Err(error) => panic!("validation unexpectedly failed: {error}"),
}
}
}