scim_server/operation_handler/
mod.rs

1//! Operation Handler Foundation
2//!
3//! This module provides a framework-agnostic operation handler that serves as the foundation
4//! for both HTTP and MCP integrations. It abstracts SCIM operations into structured
5//! request/response types while maintaining type safety and comprehensive error handling.
6//!
7//! ## ETag Concurrency Control
8//!
9//! The operation handler provides built-in support for ETag-based conditional operations:
10//!
11//! - **Automatic Version Management**: All operations include version information in responses
12//! - **Conditional Updates**: Support for If-Match style conditional operations
13//! - **Conflict Detection**: Automatic detection and handling of version conflicts
14//! - **HTTP Compliance**: RFC 7232 compliant ETag headers in metadata
15//!
16//! ## Module Structure
17//!
18//! The operation handler is organized into focused modules:
19//!
20//! - [`core`] - Core types, handler struct, and main dispatcher
21//! - [`handlers`] - Operation-specific handlers (CRUD, query, schema, utility)
22//! - [`builders`] - Builder utilities for requests and queries
23//! - [`errors`] - Error handling utilities
24//!
25//! ## Example Usage
26//!
27//! ```rust,no_run
28//! use scim_server::operation_handler::{ScimOperationHandler, ScimOperationRequest};
29//! use scim_server::resource::version::ScimVersion;
30//! use scim_server::{ScimServer, providers::InMemoryProvider};
31//! use serde_json::json;
32//!
33//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
34//! let provider = InMemoryProvider::new();
35//! let server = ScimServer::new(provider)?;
36//! let handler = ScimOperationHandler::new(server);
37//!
38//! // Regular update (returns version information)
39//! let update_request = ScimOperationRequest::update(
40//!     "User", "123", json!({"userName": "new.name", "active": true})
41//! );
42//! let response = handler.handle_operation(update_request).await;
43//! let new_etag = response.metadata.additional.get("etag").unwrap();
44//!
45//! // Conditional update with version check
46//! let version = ScimVersion::parse_http_header(new_etag.as_str().unwrap())?;
47//! let conditional_request = ScimOperationRequest::update(
48//!     "User", "123", json!({"userName": "newer.name", "active": false})
49//! ).with_expected_version(version);
50//!
51//! let conditional_response = handler.handle_operation(conditional_request).await;
52//! if conditional_response.success {
53//!     println!("Update succeeded!");
54//! } else {
55//!     println!("Version conflict: {}", conditional_response.error.unwrap());
56//! }
57//! # Ok(())
58//! # }
59//! ```
60
61mod builders;
62mod core;
63mod errors;
64mod handlers;
65
66// Re-export all public types and functions
67pub use core::{
68    OperationMetadata, ScimOperationHandler, ScimOperationRequest, ScimOperationResponse,
69    ScimOperationType, ScimQuery,
70};
71
72// Re-export builder utilities
73pub use builders::*;
74
75// Re-export error utilities for advanced usage
76pub use errors::{create_error_response, create_version_conflict_response};