scim_server/providers/
in_memory.rs

1//! Error types and statistics for in-memory resource provider implementations.
2//!
3//! This module provides error types and statistics structures that are shared
4//! between different in-memory resource provider implementations.
5//!
6//! # Key Types
7//!
8//! - [`InMemoryError`] - Provider-specific error types for in-memory operations
9//! - [`InMemoryStats`] - Resource statistics and performance metrics
10//!
11//! # Usage
12//!
13//! These types are used with `StandardResourceProvider<InMemoryStorage>`:
14//!
15//! ```rust
16//! use scim_server::providers::StandardResourceProvider;
17//! use scim_server::storage::InMemoryStorage;
18//!
19//! let storage = InMemoryStorage::new();
20//! let provider = StandardResourceProvider::new(storage);
21//! ```
22
23use thiserror::Error;
24
25/// Errors that can occur during in-memory provider operations.
26///
27/// This error type is used by in-memory resource providers to represent
28/// various failure conditions during SCIM operations.
29#[derive(Debug, Clone, Error)]
30pub enum InMemoryError {
31    #[error("Resource not found: {resource_type} with id '{id}' in tenant '{tenant_id}'")]
32    ResourceNotFound {
33        /// The type of resource that was not found
34        resource_type: String,
35        /// The ID of the resource that was not found
36        id: String,
37        /// The tenant ID where the resource was not found
38        tenant_id: String,
39    },
40
41    #[error("Duplicate attribute '{attribute}' with value '{value}' for {resource_type} in tenant '{tenant_id}'")]
42    DuplicateAttribute {
43        /// The type of resource with duplicate attribute
44        resource_type: String,
45        /// The name of the duplicate attribute
46        attribute: String,
47        /// The duplicate value
48        value: String,
49        /// The tenant ID where the duplicate was found
50        tenant_id: String,
51    },
52
53    #[error("Invalid resource data: {message}")]
54    InvalidData {
55        /// Description of the invalid data
56        message: String,
57    },
58
59    #[error("Query error: {message}")]
60    QueryError {
61        /// Description of the query error
62        message: String,
63    },
64
65    #[error("Internal error: {message}")]
66    Internal {
67        /// Description of the internal error
68        message: String,
69    },
70
71    #[error("Invalid input: {message}")]
72    InvalidInput {
73        /// Description of what input was invalid
74        message: String,
75    },
76
77    #[error("Resource not found: {resource_type} with id '{id}'")]
78    NotFound {
79        /// The type of resource that was not found
80        resource_type: String,
81        /// The ID of the resource that was not found
82        id: String,
83    },
84
85    #[error("Precondition failed: {message}")]
86    PreconditionFailed {
87        /// Description of the precondition failure
88        message: String,
89    },
90
91    #[error("Duplicate resource: {resource_type} with userName '{username}' already exists in tenant '{tenant_id}'")]
92    DuplicateUserName {
93        /// The resource type that had the duplicate
94        resource_type: String,
95        /// The duplicate userName
96        username: String,
97        /// The tenant where the duplicate was found
98        tenant_id: String,
99    },
100
101    #[error("Patch operation failed: {message}")]
102    PatchOperationFailed {
103        /// Description of why the patch operation failed
104        message: String,
105    },
106
107    #[error("Version conflict: {conflict}")]
108    VersionConflict {
109        /// Details of the version conflict
110        #[from]
111        conflict: crate::resource::version::VersionConflict,
112    },
113}
114
115
116
117/// Statistics about the in-memory provider state.
118///
119/// Provides metrics about resource counts, tenants, and resource types
120/// for monitoring and debugging purposes.
121#[derive(Debug, Clone)]
122pub struct InMemoryStats {
123    /// Number of active tenants in the provider
124    pub tenant_count: usize,
125    /// Total number of resources across all tenants
126    pub total_resources: usize,
127    /// Number of distinct resource types
128    pub resource_type_count: usize,
129    /// List of resource type names
130    pub resource_types: Vec<String>,
131}
132
133impl InMemoryStats {
134    /// Create new empty statistics.
135    pub fn new() -> Self {
136        Self {
137            tenant_count: 0,
138            total_resources: 0,
139            resource_type_count: 0,
140            resource_types: Vec::new(),
141        }
142    }
143
144    /// Check if the provider is empty (no resources).
145    pub fn is_empty(&self) -> bool {
146        self.total_resources == 0
147    }
148}
149
150impl Default for InMemoryStats {
151    fn default() -> Self {
152        Self::new()
153    }
154}