1#![cfg_attr(not(feature = "std"), no_std)]
23#![warn(missing_docs)]
24
25#[cfg(not(feature = "std"))]
26extern crate alloc;
27
28#[cfg(not(feature = "std"))]
29use alloc::{format, string::String, vec::Vec};
30
31pub mod entities;
32pub mod events;
33pub mod services;
34pub mod value_objects;
35
36pub use entities::{Frame, Stream};
38pub use events::{DomainEvent, SessionState};
39pub use services::{PriorityHeuristicConfig, compute_priority};
40pub use value_objects::{
41 JsonData, JsonPath, MAX_DESERIALIZE_DEPTH, PathSegment, Priority, Schema, SessionId, StreamId,
42};
43
44pub type DomainResult<T> = Result<T, DomainError>;
46
47#[derive(Debug, thiserror::Error)]
52#[non_exhaustive]
53pub enum DomainError {
54 #[error("Invalid state transition: {0}")]
56 InvalidStateTransition(String),
57
58 #[error("Invalid stream state: {0}")]
60 InvalidStreamState(String),
61
62 #[error("Invalid session state: {0}")]
64 InvalidSessionState(String),
65
66 #[error("Invalid frame: {0}")]
68 InvalidFrame(String),
69
70 #[error("Stream invariant violation: {0}")]
72 InvariantViolation(String),
73
74 #[error("Invalid priority value: {0}")]
76 InvalidPriority(String),
77
78 #[error("Invalid JSON path: {0}")]
80 InvalidPath(String),
81
82 #[error("Session not found: {0}")]
84 SessionNotFound(String),
85
86 #[error("Stream not found: {0}")]
88 StreamNotFound(String),
89
90 #[error("Too many streams: {0}")]
92 TooManyStreams(String),
93
94 #[error("Domain logic error: {0}")]
96 Logic(String),
97
98 #[error("I/O error: {0}")]
100 Io(String),
101
102 #[error("Resource not found: {0}")]
104 NotFound(String),
105
106 #[error("Concurrency conflict: {0}")]
108 ConcurrencyConflict(String),
109
110 #[error("Compression error: {0}")]
112 CompressionError(String),
113
114 #[error("Validation error: {0}")]
116 ValidationError(String),
117
118 #[error("Invalid input: {0}")]
120 InvalidInput(String),
121
122 #[error("Internal error: {0}")]
124 InternalError(String),
125
126 #[error("Security violation: {0}")]
128 SecurityViolation(String),
129
130 #[error("Resource exhausted: {0}")]
132 ResourceExhausted(String),
133}
134
135impl DomainError {
136 pub fn invariant_violation(message: impl Into<String>) -> Self {
138 Self::InvariantViolation(message.into())
139 }
140
141 pub fn invalid_transition(from: &str, to: &str) -> Self {
143 Self::InvalidStateTransition(format!("{from} -> {to}"))
144 }
145}
146
147impl From<String> for DomainError {
148 fn from(error: String) -> Self {
149 Self::Logic(error)
150 }
151}
152
153#[cfg(test)]
154mod tests {
155 use super::*;
156
157 #[test]
158 fn test_domain_error_creation() {
159 let err = DomainError::invariant_violation("test");
160 assert!(matches!(err, DomainError::InvariantViolation(_)));
161
162 let err = DomainError::invalid_transition("StateA", "StateB");
163 assert!(matches!(err, DomainError::InvalidStateTransition(_)));
164 }
165
166 #[test]
167 fn test_domain_result() {
168 let result: DomainResult<u32> = Ok(42);
169 assert!(result.is_ok());
170
171 let result: DomainResult<u32> = Err(DomainError::Logic("test".to_string()));
172 assert!(result.is_err());
173 }
174}