trinity-method-sdk 2.0.8 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +235 -0
- package/README.md +34 -35
- package/dist/cli/commands/deploy/agents.js +1 -1
- package/dist/cli/commands/deploy/claude-setup.js +28 -35
- package/dist/cli/commands/deploy/index.js +1 -1
- package/dist/cli/commands/deploy/knowledge-base.js +1 -1
- package/dist/cli/commands/deploy/root-files.js +1 -1
- package/dist/cli/commands/deploy/sdk-install.js +1 -1
- package/dist/cli/commands/deploy/templates.js +29 -16
- package/dist/cli/commands/update/agents.js +1 -1
- package/dist/cli/commands/update/commands.d.ts +1 -0
- package/dist/cli/commands/update/commands.js +18 -45
- package/dist/cli/commands/update/knowledge-base.js +1 -1
- package/dist/cli/commands/update/templates.js +34 -12
- package/dist/cli/utils/deploy-linting.js +1 -1
- package/dist/cli/utils/template-processor.js +1 -1
- package/dist/templates/{claude → .claude}/EMPLOYEE-DIRECTORY.md.template +1 -1
- package/dist/templates/{agents → .claude/agents}/aj-team/apo-documentation-specialist.md.template +3 -3
- package/dist/templates/{agents → .claude/agents}/aj-team/bas-quality-gate.md.template +6 -8
- package/dist/templates/{agents → .claude/agents}/aj-team/bon-dependency-manager.md.template +8 -8
- package/dist/templates/{agents → .claude/agents}/aj-team/cap-configuration-specialist.md.template +3 -3
- package/dist/templates/{agents → .claude/agents}/aj-team/dra-code-reviewer.md.template +5 -7
- package/dist/templates/{agents → .claude/agents}/aj-team/kil-task-executor.md.template +5 -7
- package/dist/templates/{agents → .claude/agents}/aj-team/uro-refactoring-specialist.md.template +3 -3
- package/dist/templates/{agents → .claude/agents}/audit/juno-auditor.md.template +7 -2
- package/dist/templates/{agents → .claude/agents}/deployment/ein-cicd.md.template +3 -4
- package/dist/templates/{agents → .claude/agents}/deployment/ino-context.md.template +6 -3
- package/dist/templates/{agents → .claude/agents}/deployment/tan-structure.md.template +4 -1
- package/dist/templates/{agents → .claude/agents}/deployment/zen-knowledge.md.template +11 -5
- package/dist/templates/{agents → .claude/agents}/leadership/aj-cc.md.template +7 -2
- package/dist/templates/{agents → .claude/agents}/leadership/aj-maestro.md.template +4 -0
- package/dist/templates/{agents → .claude/agents}/leadership/aly-cto.md.template +5 -1
- package/dist/templates/{agents → .claude/agents}/planning/eus-decomposer.md.template +4 -0
- package/dist/templates/{agents → .claude/agents}/planning/mon-requirements.md.template +4 -0
- package/dist/templates/{agents → .claude/agents}/planning/ror-design.md.template +4 -0
- package/dist/templates/{agents → .claude/agents}/planning/tra-planner.md.template +6 -0
- package/dist/templates/{shared/claude-commands → .claude/commands/execution}/trinity-audit.md.template +6 -6
- package/dist/templates/{shared/claude-commands → .claude/commands/execution}/trinity-orchestrate.md.template +5 -5
- package/dist/templates/{shared/claude-commands → .claude/commands/infrastructure}/trinity-init.md.template +12 -11
- package/dist/templates/{shared/claude-commands → .claude/commands/investigation}/trinity-create-investigation.md.template +8 -2
- package/dist/templates/{shared/claude-commands → .claude/commands/investigation}/trinity-investigate-templates.md.template +9 -5
- package/dist/templates/{shared/claude-commands → .claude/commands/investigation}/trinity-plan-investigation.md.template +11 -5
- package/dist/templates/{shared/claude-commands → .claude/commands/maintenance}/trinity-changelog.md.template +5 -4
- package/dist/templates/.claude/commands/maintenance/trinity-docs-update.md.template +279 -0
- package/dist/templates/.claude/commands/maintenance/trinity-docs.md.template +2828 -0
- package/dist/templates/{shared/claude-commands → .claude/commands/maintenance}/trinity-readme.md.template +144 -35
- package/dist/templates/{shared/claude-commands → .claude/commands/planning}/trinity-decompose.md.template +6 -4
- package/dist/templates/{shared/claude-commands → .claude/commands/planning}/trinity-design.md.template +6 -4
- package/dist/templates/{shared/claude-commands → .claude/commands/planning}/trinity-plan.md.template +7 -5
- package/dist/templates/{shared/claude-commands → .claude/commands/planning}/trinity-requirements.md.template +6 -4
- package/dist/templates/{shared/claude-commands → .claude/commands/session}/trinity-continue.md.template +9 -3
- package/dist/templates/{shared/claude-commands → .claude/commands/session}/trinity-end.md.template +8 -2
- package/dist/templates/{shared/claude-commands → .claude/commands/session}/trinity-start.md.template +8 -2
- package/dist/templates/{shared/claude-commands → .claude/commands/utility}/trinity-agents.md.template +8 -2
- package/dist/templates/{shared/claude-commands → .claude/commands/utility}/trinity-verify.md.template +9 -4
- package/dist/templates/{shared/claude-commands → .claude/commands/utility}/trinity-workorder.md.template +8 -4
- package/dist/templates/root/TRINITY.md.template +1 -1
- package/dist/templates/source/base-CLAUDE.md.template +310 -310
- package/dist/templates/source/flutter-CLAUDE.md.template +593 -593
- package/dist/templates/source/nodejs-CLAUDE.md.template +531 -531
- package/dist/templates/source/python-CLAUDE.md.template +510 -510
- package/dist/templates/source/react-CLAUDE.md.template +513 -513
- package/dist/templates/source/rust-CLAUDE.md.template +653 -653
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/AI-DEVELOPMENT-GUIDE.md.template +1 -1
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/ARCHITECTURE.md.template +3 -3
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/CODING-PRINCIPLES.md.template +1 -1
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/DOCUMENTATION-CRITERIA.md.template +1 -1
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/ISSUES.md.template +3 -3
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/TESTING-PRINCIPLES.md.template +1 -1
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/Technical-Debt.md.template +3 -3
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/To-do.md.template +3 -3
- package/dist/templates/{knowledge-base → trinity/knowledge-base}/Trinity.md.template +4 -3
- package/dist/templates/{documentation → trinity/templates/documentation}/SUBDIRECTORY-README.md.template +1 -1
- package/dist/templates/trinity/templates/documentation/api-docs/README.md.template +218 -0
- package/dist/templates/trinity/templates/documentation/configuration/documentation-structure.md.template +71 -0
- package/dist/templates/trinity/templates/documentation/configuration/env-example-generator.md.template +387 -0
- package/dist/templates/trinity/templates/documentation/discovery/api-endpoint-scanner.md.template +343 -0
- package/dist/templates/trinity/templates/documentation/discovery/component-discovery.md.template +254 -0
- package/dist/templates/trinity/templates/documentation/discovery/env-variable-extraction.md.template +316 -0
- package/dist/templates/trinity/templates/documentation/discovery/framework-detection.md.template +205 -0
- package/dist/templates/trinity/templates/documentation/guides/api-development.md.template +375 -0
- package/dist/templates/trinity/templates/documentation/guides/contributing.md.template +488 -0
- package/dist/templates/trinity/templates/documentation/guides/deployment.md.template +565 -0
- package/dist/templates/trinity/templates/documentation/guides/getting-started.md.template +118 -0
- package/dist/templates/trinity/templates/documentation/mermaid-diagrams/api-endpoint-map.md.template +56 -0
- package/dist/templates/trinity/templates/documentation/mermaid-diagrams/component-hierarchy.md.template +60 -0
- package/dist/templates/trinity/templates/documentation/mermaid-diagrams/database-er.md.template +49 -0
- package/dist/templates/trinity/templates/documentation/mermaid-diagrams/mvc-flow.md.template +41 -0
- package/dist/templates/trinity/templates/documentation/processes/error-handling-protocol.md.template +166 -0
- package/dist/templates/trinity/templates/documentation/processes/fallback-mechanism.md.template +88 -0
- package/dist/templates/trinity/templates/documentation/reports/apo-docs-update-checklist.md.template +343 -0
- package/dist/templates/trinity/templates/documentation/reports/juno-docs-update-checklist.md.template +1337 -0
- package/dist/templates/trinity/templates/documentation/reports/juno-final-report.md.template +237 -0
- package/dist/templates/trinity/templates/documentation/reports/juno-internal-report.md.template +461 -0
- package/dist/templates/trinity/templates/documentation/validation/documentation-verification-rules.md.template +379 -0
- package/dist/templates/trinity/templates/documentation/validation/juno-quality-gates.md.template +282 -0
- package/dist/templates/{investigations → trinity/templates/investigations}/bug.md.template +2 -2
- package/dist/templates/{investigations → trinity/templates/investigations}/feature.md.template +2 -2
- package/dist/templates/{investigations → trinity/templates/investigations}/performance.md.template +2 -2
- package/dist/templates/{investigations → trinity/templates/investigations}/security.md.template +2 -2
- package/dist/templates/{investigations → trinity/templates/investigations}/technical.md.template +2 -2
- package/dist/templates/{work-orders → trinity/templates/work-orders}/ANALYSIS-TEMPLATE.md.template +0 -3
- package/dist/templates/{work-orders → trinity/templates/work-orders}/AUDIT-TEMPLATE.md.template +0 -16
- package/dist/templates/{work-orders → trinity/templates/work-orders}/IMPLEMENTATION-TEMPLATE.md.template +0 -16
- package/dist/templates/{work-orders → trinity/templates/work-orders}/INVESTIGATION-TEMPLATE.md.template +0 -15
- package/dist/templates/{work-orders → trinity/templates/work-orders}/PATTERN-TEMPLATE.md.template +0 -16
- package/dist/templates/{work-orders → trinity/templates/work-orders}/VERIFICATION-TEMPLATE.md.template +0 -16
- package/package.json +1 -1
- package/dist/templates/shared/claude-commands/trinity-docs.md.template +0 -2208
- /package/dist/templates/{linting → root/linting}/flutter/.pre-commit-config.yaml.template +0 -0
- /package/dist/templates/{linting → root/linting}/flutter/analysis_options.yaml.template +0 -0
- /package/dist/templates/{linting → root/linting}/nodejs/.eslintrc-commonjs.json.template +0 -0
- /package/dist/templates/{linting → root/linting}/nodejs/.eslintrc-esm.json.template +0 -0
- /package/dist/templates/{linting → root/linting}/nodejs/.eslintrc-typescript.json.template +0 -0
- /package/dist/templates/{linting → root/linting}/nodejs/.pre-commit-config.yaml.template +0 -0
- /package/dist/templates/{linting → root/linting}/nodejs/.prettierrc.json.template +0 -0
- /package/dist/templates/{linting → root/linting}/python/.flake8.template +0 -0
- /package/dist/templates/{linting → root/linting}/python/.pre-commit-config.yaml.template +0 -0
- /package/dist/templates/{linting → root/linting}/python/pyproject.toml.template +0 -0
- /package/dist/templates/{linting → root/linting}/rust/.pre-commit-config.yaml.template +0 -0
- /package/dist/templates/{linting → root/linting}/rust/clippy.toml.template +0 -0
- /package/dist/templates/{linting → root/linting}/rust/rustfmt.toml.template +0 -0
- /package/dist/templates/{documentation → trinity/templates/documentation}/ROOT-README.md.template +0 -0
|
@@ -1,653 +1,653 @@
|
|
|
1
|
-
# CLAUDE.md - Rust Technology-Specific Rules
|
|
2
|
-
## {{PROJECT_NAME}} - Rust Implementation
|
|
3
|
-
|
|
4
|
-
**Framework:** {{FRAMEWORK}}
|
|
5
|
-
**Language:** Rust
|
|
6
|
-
**Source Directory:** {{SOURCE_DIR}}
|
|
7
|
-
**Build Tool:** Cargo
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Technology Stack Behavioral Modifications
|
|
12
|
-
|
|
13
|
-
### Rust-Specific Requirements
|
|
14
|
-
- **Ownership & Borrowing**: Leverage Rust's ownership system for memory safety
|
|
15
|
-
- **Error Handling**: Use Result<T, E> and Option<T> for explicit error handling
|
|
16
|
-
- **Trait System**: Design using traits for abstraction and code reuse
|
|
17
|
-
- **Zero-Cost Abstractions**: Use high-level constructs without runtime overhead
|
|
18
|
-
- **Fearless Concurrency**: Utilize Rust's concurrency primitives safely
|
|
19
|
-
|
|
20
|
-
### Framework-Specific Adaptations
|
|
21
|
-
- **Tokio**: Use async/await for asynchronous I/O operations
|
|
22
|
-
- **Actix/Axum**: Follow web framework patterns and middleware design
|
|
23
|
-
- **Diesel/SQLx**: Type-safe database interactions
|
|
24
|
-
- **Cargo Workspaces**: Organize code in workspaces for modularity
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## Technology Debugging Standards
|
|
29
|
-
|
|
30
|
-
### Rust Debugging Framework
|
|
31
|
-
```rust
|
|
32
|
-
// Standard debugging format for Rust applications
|
|
33
|
-
use log::{debug, error, info, warn};
|
|
34
|
-
use std::time::Instant;
|
|
35
|
-
|
|
36
|
-
/// Debug logger for Trinity Method
|
|
37
|
-
pub struct DebugLogger {
|
|
38
|
-
module_name: String,
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
impl DebugLogger {
|
|
42
|
-
pub fn new(module_name: &str) -> Self {
|
|
43
|
-
Self {
|
|
44
|
-
module_name: module_name.to_string(),
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
pub fn entry<T: std::fmt::Debug>(&self, func_name: &str, params: &T) {
|
|
49
|
-
debug!(
|
|
50
|
-
"[ENTRY] {}.{} - Params: {:?}",
|
|
51
|
-
self.module_name, func_name, params
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
pub fn exit<T: std::fmt::Debug>(&self, func_name: &str, result: &T, duration_ms: u128) {
|
|
56
|
-
debug!(
|
|
57
|
-
"[EXIT] {}.{} - Duration: {}ms, Result: {:?}",
|
|
58
|
-
self.module_name, func_name, duration_ms, result
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
pub fn error(&self, func_name: &str, error: &dyn std::error::Error) {
|
|
63
|
-
error!(
|
|
64
|
-
"[ERROR] {}.{} - Error: {}",
|
|
65
|
-
self.module_name, func_name, error
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Usage example
|
|
71
|
-
pub struct UserService {
|
|
72
|
-
logger: DebugLogger,
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
impl UserService {
|
|
76
|
-
pub fn new() -> Self {
|
|
77
|
-
Self {
|
|
78
|
-
logger: DebugLogger::new("UserService"),
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
pub fn get_user(&self, user_id: &str) -> Result<User, Box<dyn std::error::Error>> {
|
|
83
|
-
let start = Instant::now();
|
|
84
|
-
self.logger.entry("get_user", &user_id);
|
|
85
|
-
|
|
86
|
-
let result = self.fetch_user_internal(user_id);
|
|
87
|
-
|
|
88
|
-
match &result {
|
|
89
|
-
Ok(user) => {
|
|
90
|
-
self.logger.exit("get_user", user, start.elapsed().as_millis());
|
|
91
|
-
}
|
|
92
|
-
Err(e) => {
|
|
93
|
-
self.logger.error("get_user", e.as_ref());
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
result
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
fn fetch_user_internal(&self, user_id: &str) -> Result<User, Box<dyn std::error::Error>> {
|
|
101
|
-
// Implementation
|
|
102
|
-
Ok(User {
|
|
103
|
-
id: user_id.to_string(),
|
|
104
|
-
name: "John Doe".to_string(),
|
|
105
|
-
})
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
#[derive(Debug)]
|
|
110
|
-
pub struct User {
|
|
111
|
-
pub id: String,
|
|
112
|
-
pub name: String,
|
|
113
|
-
}
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
## Performance Optimization Rules
|
|
119
|
-
|
|
120
|
-
### Rust Performance Monitoring
|
|
121
|
-
```rust
|
|
122
|
-
// Performance measurement utilities
|
|
123
|
-
use std::time::{Duration, Instant};
|
|
124
|
-
|
|
125
|
-
pub struct PerformanceMonitor;
|
|
126
|
-
|
|
127
|
-
impl PerformanceMonitor {
|
|
128
|
-
/// Measure synchronous operation
|
|
129
|
-
pub fn measure<F, T>(name: &str, operation: F) -> T
|
|
130
|
-
where
|
|
131
|
-
F: FnOnce() -> T,
|
|
132
|
-
{
|
|
133
|
-
let start = Instant::now();
|
|
134
|
-
|
|
135
|
-
let result = operation();
|
|
136
|
-
|
|
137
|
-
let duration = start.elapsed();
|
|
138
|
-
println!("[PERF] {}: {:?}", name, duration);
|
|
139
|
-
|
|
140
|
-
result
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/// Measure async operation
|
|
144
|
-
pub async fn measure_async<F, Fut, T>(name: &str, operation: F) -> T
|
|
145
|
-
where
|
|
146
|
-
F: FnOnce() -> Fut,
|
|
147
|
-
Fut: std::future::Future<Output = T>,
|
|
148
|
-
{
|
|
149
|
-
let start = Instant::now();
|
|
150
|
-
|
|
151
|
-
let result = operation().await;
|
|
152
|
-
|
|
153
|
-
let duration = start.elapsed();
|
|
154
|
-
println!("[PERF] {}: {:?}", name, duration);
|
|
155
|
-
|
|
156
|
-
result
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Usage
|
|
161
|
-
let users = PerformanceMonitor::measure("fetch_users", || {
|
|
162
|
-
database.query_users()
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
let result = PerformanceMonitor::measure_async("async_fetch", || {
|
|
166
|
-
async_database.query_users()
|
|
167
|
-
}).await;
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### Memory Efficiency
|
|
171
|
-
```rust
|
|
172
|
-
// Use references to avoid unnecessary clones
|
|
173
|
-
fn process_large_data(data: &Vec<u8>) -> usize {
|
|
174
|
-
data.len()
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Use iterators for lazy evaluation
|
|
178
|
-
fn sum_even_numbers(numbers: &[i32]) -> i32 {
|
|
179
|
-
numbers
|
|
180
|
-
.iter()
|
|
181
|
-
.filter(|&&n| n % 2 == 0)
|
|
182
|
-
.sum()
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Use Cow for conditional ownership
|
|
186
|
-
use std::borrow::Cow;
|
|
187
|
-
|
|
188
|
-
fn modify_if_needed(input: &str) -> Cow<str> {
|
|
189
|
-
if input.contains("replace") {
|
|
190
|
-
Cow::Owned(input.replace("replace", "updated"))
|
|
191
|
-
} else {
|
|
192
|
-
Cow::Borrowed(input)
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
---
|
|
198
|
-
|
|
199
|
-
## Security Best Practices
|
|
200
|
-
|
|
201
|
-
### Input Validation
|
|
202
|
-
```rust
|
|
203
|
-
// Input validation with thiserror
|
|
204
|
-
use thiserror::Error;
|
|
205
|
-
|
|
206
|
-
#[derive(Error, Debug)]
|
|
207
|
-
pub enum ValidationError {
|
|
208
|
-
#[error("Email format is invalid: {0}")]
|
|
209
|
-
InvalidEmail(String),
|
|
210
|
-
|
|
211
|
-
#[error("Password too short: minimum {min} characters, got {actual}")]
|
|
212
|
-
PasswordTooShort { min: usize, actual: usize },
|
|
213
|
-
|
|
214
|
-
#[error("Username contains invalid characters")]
|
|
215
|
-
InvalidUsername,
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
pub struct InputValidator;
|
|
219
|
-
|
|
220
|
-
impl InputValidator {
|
|
221
|
-
pub fn validate_email(email: &str) -> Result<(), ValidationError> {
|
|
222
|
-
let email_regex = regex::Regex::new(r"^[\w\.-]+@[\w\.-]+\.\w{2,}$").unwrap();
|
|
223
|
-
|
|
224
|
-
if !email_regex.is_match(email) {
|
|
225
|
-
return Err(ValidationError::InvalidEmail(email.to_string()));
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
Ok(())
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
pub fn validate_password(password: &str) -> Result<(), ValidationError> {
|
|
232
|
-
const MIN_LENGTH: usize = 8;
|
|
233
|
-
|
|
234
|
-
if password.len() < MIN_LENGTH {
|
|
235
|
-
return Err(ValidationError::PasswordTooShort {
|
|
236
|
-
min: MIN_LENGTH,
|
|
237
|
-
actual: password.len(),
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
Ok(())
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
### Safe Concurrency
|
|
247
|
-
```rust
|
|
248
|
-
// Use Arc and Mutex for shared state
|
|
249
|
-
use std::sync::{Arc, Mutex};
|
|
250
|
-
use std::thread;
|
|
251
|
-
|
|
252
|
-
pub struct SafeCounter {
|
|
253
|
-
count: Arc<Mutex<i32>>,
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
impl SafeCounter {
|
|
257
|
-
pub fn new() -> Self {
|
|
258
|
-
Self {
|
|
259
|
-
count: Arc::new(Mutex::new(0)),
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
pub fn increment(&self) {
|
|
264
|
-
let mut count = self.count.lock().unwrap();
|
|
265
|
-
*count += 1;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
pub fn value(&self) -> i32 {
|
|
269
|
-
*self.count.lock().unwrap()
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
---
|
|
275
|
-
|
|
276
|
-
## Testing Requirements
|
|
277
|
-
|
|
278
|
-
### Unit Testing
|
|
279
|
-
```rust
|
|
280
|
-
#[cfg(test)]
|
|
281
|
-
mod tests {
|
|
282
|
-
use super::*;
|
|
283
|
-
|
|
284
|
-
#[test]
|
|
285
|
-
fn test_get_user_success() {
|
|
286
|
-
let service = UserService::new();
|
|
287
|
-
|
|
288
|
-
let result = service.get_user("123");
|
|
289
|
-
|
|
290
|
-
assert!(result.is_ok());
|
|
291
|
-
let user = result.unwrap();
|
|
292
|
-
assert_eq!(user.id, "123");
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
#[test]
|
|
296
|
-
fn test_get_user_not_found() {
|
|
297
|
-
let service = UserService::new();
|
|
298
|
-
|
|
299
|
-
let result = service.get_user("invalid");
|
|
300
|
-
|
|
301
|
-
assert!(result.is_err());
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
#[test]
|
|
305
|
-
#[should_panic(expected = "Invalid input")]
|
|
306
|
-
fn test_panic_scenario() {
|
|
307
|
-
panic!("Invalid input");
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
### Integration Testing
|
|
313
|
-
```rust
|
|
314
|
-
// Integration tests in tests/ directory
|
|
315
|
-
#[cfg(test)]
|
|
316
|
-
mod integration_tests {
|
|
317
|
-
use super::*;
|
|
318
|
-
|
|
319
|
-
#[tokio::test]
|
|
320
|
-
async fn test_api_endpoint() {
|
|
321
|
-
let app = create_test_app().await;
|
|
322
|
-
|
|
323
|
-
let response = app
|
|
324
|
-
.oneshot(
|
|
325
|
-
Request::builder()
|
|
326
|
-
.uri("/api/users/123")
|
|
327
|
-
.body(Body::empty())
|
|
328
|
-
.unwrap(),
|
|
329
|
-
)
|
|
330
|
-
.await
|
|
331
|
-
.unwrap();
|
|
332
|
-
|
|
333
|
-
assert_eq!(response.status(), StatusCode::OK);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
### Property-Based Testing
|
|
339
|
-
```rust
|
|
340
|
-
// Using proptest for property-based testing
|
|
341
|
-
#[cfg(test)]
|
|
342
|
-
mod proptests {
|
|
343
|
-
use proptest::prelude::*;
|
|
344
|
-
|
|
345
|
-
proptest! {
|
|
346
|
-
#[test]
|
|
347
|
-
fn test_reverse_twice_is_identity(s: String) {
|
|
348
|
-
let reversed = s.chars().rev().collect::<String>();
|
|
349
|
-
let double_reversed = reversed.chars().rev().collect::<String>();
|
|
350
|
-
prop_assert_eq!(s, double_reversed);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
---
|
|
357
|
-
|
|
358
|
-
## Framework Best Practices
|
|
359
|
-
|
|
360
|
-
### Axum Web Framework Pattern
|
|
361
|
-
```rust
|
|
362
|
-
// Axum application structure
|
|
363
|
-
use axum::{
|
|
364
|
-
extract::{Path, State},
|
|
365
|
-
http::StatusCode,
|
|
366
|
-
response::Json,
|
|
367
|
-
routing::get,
|
|
368
|
-
Router,
|
|
369
|
-
};
|
|
370
|
-
use serde::{Deserialize, Serialize};
|
|
371
|
-
use std::sync::Arc;
|
|
372
|
-
|
|
373
|
-
#[derive(Clone)]
|
|
374
|
-
pub struct AppState {
|
|
375
|
-
logger: Arc<DebugLogger>,
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
#[derive(Serialize, Deserialize)]
|
|
379
|
-
pub struct UserResponse {
|
|
380
|
-
id: String,
|
|
381
|
-
name: String,
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
pub async fn get_user(
|
|
385
|
-
Path(user_id): Path<String>,
|
|
386
|
-
State(state): State<AppState>,
|
|
387
|
-
) -> Result<Json<UserResponse>, (StatusCode, String)> {
|
|
388
|
-
let start = Instant::now();
|
|
389
|
-
state.logger.entry("get_user", &user_id);
|
|
390
|
-
|
|
391
|
-
// Fetch user logic
|
|
392
|
-
let user = UserResponse {
|
|
393
|
-
id: user_id.clone(),
|
|
394
|
-
name: "John Doe".to_string(),
|
|
395
|
-
};
|
|
396
|
-
|
|
397
|
-
state.logger.exit("get_user", &user, start.elapsed().as_millis());
|
|
398
|
-
|
|
399
|
-
Ok(Json(user))
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
pub fn create_router() -> Router {
|
|
403
|
-
let state = AppState {
|
|
404
|
-
logger: Arc::new(DebugLogger::new("AxumApp")),
|
|
405
|
-
};
|
|
406
|
-
|
|
407
|
-
Router::new()
|
|
408
|
-
.route("/api/users/:id", get(get_user))
|
|
409
|
-
.with_state(state)
|
|
410
|
-
}
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
### Diesel ORM Pattern
|
|
414
|
-
```rust
|
|
415
|
-
// Diesel database operations
|
|
416
|
-
use diesel::prelude::*;
|
|
417
|
-
|
|
418
|
-
pub struct UserRepository {
|
|
419
|
-
logger: DebugLogger,
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
impl UserRepository {
|
|
423
|
-
pub fn new() -> Self {
|
|
424
|
-
Self {
|
|
425
|
-
logger: DebugLogger::new("UserRepository"),
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
pub fn find_by_id(
|
|
430
|
-
&self,
|
|
431
|
-
conn: &mut PgConnection,
|
|
432
|
-
user_id: &str,
|
|
433
|
-
) -> Result<User, diesel::result::Error> {
|
|
434
|
-
let start = Instant::now();
|
|
435
|
-
self.logger.entry("find_by_id", &user_id);
|
|
436
|
-
|
|
437
|
-
let result = users::table
|
|
438
|
-
.filter(users::id.eq(user_id))
|
|
439
|
-
.first::<User>(conn);
|
|
440
|
-
|
|
441
|
-
match &result {
|
|
442
|
-
Ok(user) => {
|
|
443
|
-
self.logger.exit("find_by_id", user, start.elapsed().as_millis());
|
|
444
|
-
}
|
|
445
|
-
Err(e) => {
|
|
446
|
-
self.logger.error("find_by_id", e);
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
result
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
---
|
|
456
|
-
|
|
457
|
-
## Error Handling Patterns
|
|
458
|
-
|
|
459
|
-
### Custom Error Types
|
|
460
|
-
```rust
|
|
461
|
-
// Comprehensive error handling with thiserror
|
|
462
|
-
use thiserror::Error;
|
|
463
|
-
|
|
464
|
-
#[derive(Error, Debug)]
|
|
465
|
-
pub enum ApplicationError {
|
|
466
|
-
#[error("Database error: {0}")]
|
|
467
|
-
Database(#[from] diesel::result::Error),
|
|
468
|
-
|
|
469
|
-
#[error("Validation error: {0}")]
|
|
470
|
-
Validation(#[from] ValidationError),
|
|
471
|
-
|
|
472
|
-
#[error("User not found: {0}")]
|
|
473
|
-
NotFound(String),
|
|
474
|
-
|
|
475
|
-
#[error("Internal server error: {0}")]
|
|
476
|
-
Internal(String),
|
|
477
|
-
|
|
478
|
-
#[error("Unauthorized: {0}")]
|
|
479
|
-
Unauthorized(String),
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
impl ApplicationError {
|
|
483
|
-
pub fn status_code(&self) -> StatusCode {
|
|
484
|
-
match self {
|
|
485
|
-
Self::Database(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
|
486
|
-
Self::Validation(_) => StatusCode::BAD_REQUEST,
|
|
487
|
-
Self::NotFound(_) => StatusCode::NOT_FOUND,
|
|
488
|
-
Self::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
|
489
|
-
Self::Unauthorized(_) => StatusCode::UNAUTHORIZED,
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
```
|
|
494
|
-
|
|
495
|
-
### Result Type Patterns
|
|
496
|
-
```rust
|
|
497
|
-
// Use Result for error propagation
|
|
498
|
-
pub fn safe_operation() -> Result<String, ApplicationError> {
|
|
499
|
-
let value = risky_operation()?;
|
|
500
|
-
let processed = process_value(&value)?;
|
|
501
|
-
Ok(processed)
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
// Custom Result alias
|
|
505
|
-
pub type AppResult<T> = Result<T, ApplicationError>;
|
|
506
|
-
|
|
507
|
-
pub fn get_user(id: &str) -> AppResult<User> {
|
|
508
|
-
validate_id(id)?;
|
|
509
|
-
let user = fetch_from_database(id)?;
|
|
510
|
-
Ok(user)
|
|
511
|
-
}
|
|
512
|
-
```
|
|
513
|
-
|
|
514
|
-
---
|
|
515
|
-
|
|
516
|
-
## Technology-Specific Command References
|
|
517
|
-
|
|
518
|
-
### Development Commands
|
|
519
|
-
```bash
|
|
520
|
-
# Rust Development
|
|
521
|
-
cargo run # Run application
|
|
522
|
-
cargo run --release # Run optimized build
|
|
523
|
-
cargo run --bin server # Run specific binary
|
|
524
|
-
cargo watch -x run # Auto-reload on changes
|
|
525
|
-
|
|
526
|
-
# Build Commands
|
|
527
|
-
cargo build # Debug build
|
|
528
|
-
cargo build --release # Production build
|
|
529
|
-
cargo check # Fast check without building
|
|
530
|
-
cargo clippy # Lint code
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
### Testing Commands
|
|
534
|
-
```bash
|
|
535
|
-
# Testing
|
|
536
|
-
cargo test # Run all tests
|
|
537
|
-
cargo test --lib # Library tests only
|
|
538
|
-
cargo test --test integration # Integration tests
|
|
539
|
-
cargo test -- --nocapture # Show println! output
|
|
540
|
-
cargo test --release # Test optimized build
|
|
541
|
-
|
|
542
|
-
# Coverage
|
|
543
|
-
cargo tarpaulin # Generate coverage (with tarpaulin)
|
|
544
|
-
cargo llvm-cov # Generate coverage (with llvm-cov)
|
|
545
|
-
```
|
|
546
|
-
|
|
547
|
-
### Documentation Commands
|
|
548
|
-
```bash
|
|
549
|
-
# Documentation
|
|
550
|
-
cargo doc # Generate documentation
|
|
551
|
-
cargo doc --open # Generate and open docs
|
|
552
|
-
cargo doc --no-deps # Only document this crate
|
|
553
|
-
```
|
|
554
|
-
|
|
555
|
-
---
|
|
556
|
-
|
|
557
|
-
## Trait System Best Practices
|
|
558
|
-
|
|
559
|
-
### Trait Design
|
|
560
|
-
```rust
|
|
561
|
-
// Design with traits for abstraction
|
|
562
|
-
pub trait Repository<T> {
|
|
563
|
-
fn find_by_id(&self, id: &str) -> AppResult<T>;
|
|
564
|
-
fn find_all(&self) -> AppResult<Vec<T>>;
|
|
565
|
-
fn save(&self, entity: &T) -> AppResult<T>;
|
|
566
|
-
fn delete(&self, id: &str) -> AppResult<()>;
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
// Implement for specific types
|
|
570
|
-
impl Repository<User> for UserRepository {
|
|
571
|
-
fn find_by_id(&self, id: &str) -> AppResult<User> {
|
|
572
|
-
// Implementation
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
fn find_all(&self) -> AppResult<Vec<User>> {
|
|
576
|
-
// Implementation
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
fn save(&self, user: &User) -> AppResult<User> {
|
|
580
|
-
// Implementation
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
fn delete(&self, id: &str) -> AppResult<()> {
|
|
584
|
-
// Implementation
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
```
|
|
588
|
-
|
|
589
|
-
---
|
|
590
|
-
|
|
591
|
-
## Async/Await Patterns
|
|
592
|
-
|
|
593
|
-
### Tokio Async Runtime
|
|
594
|
-
```rust
|
|
595
|
-
// Async function with Tokio
|
|
596
|
-
use tokio::time::{sleep, Duration};
|
|
597
|
-
|
|
598
|
-
pub async fn fetch_user_async(user_id: &str) -> AppResult<User> {
|
|
599
|
-
let logger = DebugLogger::new("AsyncUserService");
|
|
600
|
-
let start = Instant::now();
|
|
601
|
-
logger.entry("fetch_user_async", &user_id);
|
|
602
|
-
|
|
603
|
-
// Async operation
|
|
604
|
-
sleep(Duration::from_millis(100)).await;
|
|
605
|
-
|
|
606
|
-
let user = User {
|
|
607
|
-
id: user_id.to_string(),
|
|
608
|
-
name: "John Doe".to_string(),
|
|
609
|
-
};
|
|
610
|
-
|
|
611
|
-
logger.exit("fetch_user_async", &user, start.elapsed().as_millis());
|
|
612
|
-
|
|
613
|
-
Ok(user)
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
// Spawn concurrent tasks
|
|
617
|
-
pub async fn fetch_multiple_users(user_ids: Vec<String>) -> Vec<AppResult<User>> {
|
|
618
|
-
let tasks: Vec<_> = user_ids
|
|
619
|
-
.into_iter()
|
|
620
|
-
.map(|id| tokio::spawn(fetch_user_async(id)))
|
|
621
|
-
.collect();
|
|
622
|
-
|
|
623
|
-
let results = futures::future::join_all(tasks).await;
|
|
624
|
-
|
|
625
|
-
results
|
|
626
|
-
.into_iter()
|
|
627
|
-
.map(|r| r.unwrap())
|
|
628
|
-
.collect()
|
|
629
|
-
}
|
|
630
|
-
```
|
|
631
|
-
|
|
632
|
-
---
|
|
633
|
-
|
|
634
|
-
## Reference to Parent Context
|
|
635
|
-
|
|
636
|
-
This file extends the Trinity Method protocols defined in `../trinity/CLAUDE.md` and global requirements from `../CLAUDE.md`. Rust implementations must comply with:
|
|
637
|
-
|
|
638
|
-
- Trinity Method investigation requirements ([../trinity/CLAUDE.md](../trinity/CLAUDE.md))
|
|
639
|
-
- Global performance baselines ([../trinity/knowledge-base/ARCHITECTURE.md](../trinity/knowledge-base/ARCHITECTURE.md#performance-baseline))
|
|
640
|
-
- Quality gate standards (BAS 6-phase) ([../trinity/CLAUDE.md](../trinity/CLAUDE.md#quality-standards))
|
|
641
|
-
- Crisis management protocols ([../trinity/CLAUDE.md](../trinity/CLAUDE.md#crisis-management))
|
|
642
|
-
|
|
643
|
-
All Rust code must implement the debugging frameworks, error handling patterns, and performance monitoring specified in this document.
|
|
644
|
-
|
|
645
|
-
---
|
|
646
|
-
|
|
647
|
-
**Technology Context**: Rust Implementation
|
|
648
|
-
**Parent References**:
|
|
649
|
-
- `../CLAUDE.md` - Global project requirements
|
|
650
|
-
- `../trinity/CLAUDE.md` - Trinity Method enforcement
|
|
651
|
-
|
|
652
|
-
**Last Updated**: {{CURRENT_DATE}}
|
|
653
|
-
**Trinity Version**: {{TRINITY_VERSION}}
|
|
1
|
+
# CLAUDE.md - Rust Technology-Specific Rules
|
|
2
|
+
## {{PROJECT_NAME}} - Rust Implementation
|
|
3
|
+
|
|
4
|
+
**Framework:** {{FRAMEWORK}}
|
|
5
|
+
**Language:** Rust
|
|
6
|
+
**Source Directory:** {{SOURCE_DIR}}
|
|
7
|
+
**Build Tool:** Cargo
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Technology Stack Behavioral Modifications
|
|
12
|
+
|
|
13
|
+
### Rust-Specific Requirements
|
|
14
|
+
- **Ownership & Borrowing**: Leverage Rust's ownership system for memory safety
|
|
15
|
+
- **Error Handling**: Use Result<T, E> and Option<T> for explicit error handling
|
|
16
|
+
- **Trait System**: Design using traits for abstraction and code reuse
|
|
17
|
+
- **Zero-Cost Abstractions**: Use high-level constructs without runtime overhead
|
|
18
|
+
- **Fearless Concurrency**: Utilize Rust's concurrency primitives safely
|
|
19
|
+
|
|
20
|
+
### Framework-Specific Adaptations
|
|
21
|
+
- **Tokio**: Use async/await for asynchronous I/O operations
|
|
22
|
+
- **Actix/Axum**: Follow web framework patterns and middleware design
|
|
23
|
+
- **Diesel/SQLx**: Type-safe database interactions
|
|
24
|
+
- **Cargo Workspaces**: Organize code in workspaces for modularity
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Technology Debugging Standards
|
|
29
|
+
|
|
30
|
+
### Rust Debugging Framework
|
|
31
|
+
```rust
|
|
32
|
+
// Standard debugging format for Rust applications
|
|
33
|
+
use log::{debug, error, info, warn};
|
|
34
|
+
use std::time::Instant;
|
|
35
|
+
|
|
36
|
+
/// Debug logger for Trinity Method
|
|
37
|
+
pub struct DebugLogger {
|
|
38
|
+
module_name: String,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
impl DebugLogger {
|
|
42
|
+
pub fn new(module_name: &str) -> Self {
|
|
43
|
+
Self {
|
|
44
|
+
module_name: module_name.to_string(),
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
pub fn entry<T: std::fmt::Debug>(&self, func_name: &str, params: &T) {
|
|
49
|
+
debug!(
|
|
50
|
+
"[ENTRY] {}.{} - Params: {:?}",
|
|
51
|
+
self.module_name, func_name, params
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
pub fn exit<T: std::fmt::Debug>(&self, func_name: &str, result: &T, duration_ms: u128) {
|
|
56
|
+
debug!(
|
|
57
|
+
"[EXIT] {}.{} - Duration: {}ms, Result: {:?}",
|
|
58
|
+
self.module_name, func_name, duration_ms, result
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
pub fn error(&self, func_name: &str, error: &dyn std::error::Error) {
|
|
63
|
+
error!(
|
|
64
|
+
"[ERROR] {}.{} - Error: {}",
|
|
65
|
+
self.module_name, func_name, error
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Usage example
|
|
71
|
+
pub struct UserService {
|
|
72
|
+
logger: DebugLogger,
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
impl UserService {
|
|
76
|
+
pub fn new() -> Self {
|
|
77
|
+
Self {
|
|
78
|
+
logger: DebugLogger::new("UserService"),
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
pub fn get_user(&self, user_id: &str) -> Result<User, Box<dyn std::error::Error>> {
|
|
83
|
+
let start = Instant::now();
|
|
84
|
+
self.logger.entry("get_user", &user_id);
|
|
85
|
+
|
|
86
|
+
let result = self.fetch_user_internal(user_id);
|
|
87
|
+
|
|
88
|
+
match &result {
|
|
89
|
+
Ok(user) => {
|
|
90
|
+
self.logger.exit("get_user", user, start.elapsed().as_millis());
|
|
91
|
+
}
|
|
92
|
+
Err(e) => {
|
|
93
|
+
self.logger.error("get_user", e.as_ref());
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
result
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
fn fetch_user_internal(&self, user_id: &str) -> Result<User, Box<dyn std::error::Error>> {
|
|
101
|
+
// Implementation
|
|
102
|
+
Ok(User {
|
|
103
|
+
id: user_id.to_string(),
|
|
104
|
+
name: "John Doe".to_string(),
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
#[derive(Debug)]
|
|
110
|
+
pub struct User {
|
|
111
|
+
pub id: String,
|
|
112
|
+
pub name: String,
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Performance Optimization Rules
|
|
119
|
+
|
|
120
|
+
### Rust Performance Monitoring
|
|
121
|
+
```rust
|
|
122
|
+
// Performance measurement utilities
|
|
123
|
+
use std::time::{Duration, Instant};
|
|
124
|
+
|
|
125
|
+
pub struct PerformanceMonitor;
|
|
126
|
+
|
|
127
|
+
impl PerformanceMonitor {
|
|
128
|
+
/// Measure synchronous operation
|
|
129
|
+
pub fn measure<F, T>(name: &str, operation: F) -> T
|
|
130
|
+
where
|
|
131
|
+
F: FnOnce() -> T,
|
|
132
|
+
{
|
|
133
|
+
let start = Instant::now();
|
|
134
|
+
|
|
135
|
+
let result = operation();
|
|
136
|
+
|
|
137
|
+
let duration = start.elapsed();
|
|
138
|
+
println!("[PERF] {}: {:?}", name, duration);
|
|
139
|
+
|
|
140
|
+
result
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/// Measure async operation
|
|
144
|
+
pub async fn measure_async<F, Fut, T>(name: &str, operation: F) -> T
|
|
145
|
+
where
|
|
146
|
+
F: FnOnce() -> Fut,
|
|
147
|
+
Fut: std::future::Future<Output = T>,
|
|
148
|
+
{
|
|
149
|
+
let start = Instant::now();
|
|
150
|
+
|
|
151
|
+
let result = operation().await;
|
|
152
|
+
|
|
153
|
+
let duration = start.elapsed();
|
|
154
|
+
println!("[PERF] {}: {:?}", name, duration);
|
|
155
|
+
|
|
156
|
+
result
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Usage
|
|
161
|
+
let users = PerformanceMonitor::measure("fetch_users", || {
|
|
162
|
+
database.query_users()
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
let result = PerformanceMonitor::measure_async("async_fetch", || {
|
|
166
|
+
async_database.query_users()
|
|
167
|
+
}).await;
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Memory Efficiency
|
|
171
|
+
```rust
|
|
172
|
+
// Use references to avoid unnecessary clones
|
|
173
|
+
fn process_large_data(data: &Vec<u8>) -> usize {
|
|
174
|
+
data.len()
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Use iterators for lazy evaluation
|
|
178
|
+
fn sum_even_numbers(numbers: &[i32]) -> i32 {
|
|
179
|
+
numbers
|
|
180
|
+
.iter()
|
|
181
|
+
.filter(|&&n| n % 2 == 0)
|
|
182
|
+
.sum()
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Use Cow for conditional ownership
|
|
186
|
+
use std::borrow::Cow;
|
|
187
|
+
|
|
188
|
+
fn modify_if_needed(input: &str) -> Cow<str> {
|
|
189
|
+
if input.contains("replace") {
|
|
190
|
+
Cow::Owned(input.replace("replace", "updated"))
|
|
191
|
+
} else {
|
|
192
|
+
Cow::Borrowed(input)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Security Best Practices
|
|
200
|
+
|
|
201
|
+
### Input Validation
|
|
202
|
+
```rust
|
|
203
|
+
// Input validation with thiserror
|
|
204
|
+
use thiserror::Error;
|
|
205
|
+
|
|
206
|
+
#[derive(Error, Debug)]
|
|
207
|
+
pub enum ValidationError {
|
|
208
|
+
#[error("Email format is invalid: {0}")]
|
|
209
|
+
InvalidEmail(String),
|
|
210
|
+
|
|
211
|
+
#[error("Password too short: minimum {min} characters, got {actual}")]
|
|
212
|
+
PasswordTooShort { min: usize, actual: usize },
|
|
213
|
+
|
|
214
|
+
#[error("Username contains invalid characters")]
|
|
215
|
+
InvalidUsername,
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
pub struct InputValidator;
|
|
219
|
+
|
|
220
|
+
impl InputValidator {
|
|
221
|
+
pub fn validate_email(email: &str) -> Result<(), ValidationError> {
|
|
222
|
+
let email_regex = regex::Regex::new(r"^[\w\.-]+@[\w\.-]+\.\w{2,}$").unwrap();
|
|
223
|
+
|
|
224
|
+
if !email_regex.is_match(email) {
|
|
225
|
+
return Err(ValidationError::InvalidEmail(email.to_string()));
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
Ok(())
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
pub fn validate_password(password: &str) -> Result<(), ValidationError> {
|
|
232
|
+
const MIN_LENGTH: usize = 8;
|
|
233
|
+
|
|
234
|
+
if password.len() < MIN_LENGTH {
|
|
235
|
+
return Err(ValidationError::PasswordTooShort {
|
|
236
|
+
min: MIN_LENGTH,
|
|
237
|
+
actual: password.len(),
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
Ok(())
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Safe Concurrency
|
|
247
|
+
```rust
|
|
248
|
+
// Use Arc and Mutex for shared state
|
|
249
|
+
use std::sync::{Arc, Mutex};
|
|
250
|
+
use std::thread;
|
|
251
|
+
|
|
252
|
+
pub struct SafeCounter {
|
|
253
|
+
count: Arc<Mutex<i32>>,
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
impl SafeCounter {
|
|
257
|
+
pub fn new() -> Self {
|
|
258
|
+
Self {
|
|
259
|
+
count: Arc::new(Mutex::new(0)),
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
pub fn increment(&self) {
|
|
264
|
+
let mut count = self.count.lock().unwrap();
|
|
265
|
+
*count += 1;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
pub fn value(&self) -> i32 {
|
|
269
|
+
*self.count.lock().unwrap()
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## Testing Requirements
|
|
277
|
+
|
|
278
|
+
### Unit Testing
|
|
279
|
+
```rust
|
|
280
|
+
#[cfg(test)]
|
|
281
|
+
mod tests {
|
|
282
|
+
use super::*;
|
|
283
|
+
|
|
284
|
+
#[test]
|
|
285
|
+
fn test_get_user_success() {
|
|
286
|
+
let service = UserService::new();
|
|
287
|
+
|
|
288
|
+
let result = service.get_user("123");
|
|
289
|
+
|
|
290
|
+
assert!(result.is_ok());
|
|
291
|
+
let user = result.unwrap();
|
|
292
|
+
assert_eq!(user.id, "123");
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
#[test]
|
|
296
|
+
fn test_get_user_not_found() {
|
|
297
|
+
let service = UserService::new();
|
|
298
|
+
|
|
299
|
+
let result = service.get_user("invalid");
|
|
300
|
+
|
|
301
|
+
assert!(result.is_err());
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
#[test]
|
|
305
|
+
#[should_panic(expected = "Invalid input")]
|
|
306
|
+
fn test_panic_scenario() {
|
|
307
|
+
panic!("Invalid input");
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Integration Testing
|
|
313
|
+
```rust
|
|
314
|
+
// Integration tests in tests/ directory
|
|
315
|
+
#[cfg(test)]
|
|
316
|
+
mod integration_tests {
|
|
317
|
+
use super::*;
|
|
318
|
+
|
|
319
|
+
#[tokio::test]
|
|
320
|
+
async fn test_api_endpoint() {
|
|
321
|
+
let app = create_test_app().await;
|
|
322
|
+
|
|
323
|
+
let response = app
|
|
324
|
+
.oneshot(
|
|
325
|
+
Request::builder()
|
|
326
|
+
.uri("/api/users/123")
|
|
327
|
+
.body(Body::empty())
|
|
328
|
+
.unwrap(),
|
|
329
|
+
)
|
|
330
|
+
.await
|
|
331
|
+
.unwrap();
|
|
332
|
+
|
|
333
|
+
assert_eq!(response.status(), StatusCode::OK);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Property-Based Testing
|
|
339
|
+
```rust
|
|
340
|
+
// Using proptest for property-based testing
|
|
341
|
+
#[cfg(test)]
|
|
342
|
+
mod proptests {
|
|
343
|
+
use proptest::prelude::*;
|
|
344
|
+
|
|
345
|
+
proptest! {
|
|
346
|
+
#[test]
|
|
347
|
+
fn test_reverse_twice_is_identity(s: String) {
|
|
348
|
+
let reversed = s.chars().rev().collect::<String>();
|
|
349
|
+
let double_reversed = reversed.chars().rev().collect::<String>();
|
|
350
|
+
prop_assert_eq!(s, double_reversed);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## Framework Best Practices
|
|
359
|
+
|
|
360
|
+
### Axum Web Framework Pattern
|
|
361
|
+
```rust
|
|
362
|
+
// Axum application structure
|
|
363
|
+
use axum::{
|
|
364
|
+
extract::{Path, State},
|
|
365
|
+
http::StatusCode,
|
|
366
|
+
response::Json,
|
|
367
|
+
routing::get,
|
|
368
|
+
Router,
|
|
369
|
+
};
|
|
370
|
+
use serde::{Deserialize, Serialize};
|
|
371
|
+
use std::sync::Arc;
|
|
372
|
+
|
|
373
|
+
#[derive(Clone)]
|
|
374
|
+
pub struct AppState {
|
|
375
|
+
logger: Arc<DebugLogger>,
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
#[derive(Serialize, Deserialize)]
|
|
379
|
+
pub struct UserResponse {
|
|
380
|
+
id: String,
|
|
381
|
+
name: String,
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
pub async fn get_user(
|
|
385
|
+
Path(user_id): Path<String>,
|
|
386
|
+
State(state): State<AppState>,
|
|
387
|
+
) -> Result<Json<UserResponse>, (StatusCode, String)> {
|
|
388
|
+
let start = Instant::now();
|
|
389
|
+
state.logger.entry("get_user", &user_id);
|
|
390
|
+
|
|
391
|
+
// Fetch user logic
|
|
392
|
+
let user = UserResponse {
|
|
393
|
+
id: user_id.clone(),
|
|
394
|
+
name: "John Doe".to_string(),
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
state.logger.exit("get_user", &user, start.elapsed().as_millis());
|
|
398
|
+
|
|
399
|
+
Ok(Json(user))
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
pub fn create_router() -> Router {
|
|
403
|
+
let state = AppState {
|
|
404
|
+
logger: Arc::new(DebugLogger::new("AxumApp")),
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
Router::new()
|
|
408
|
+
.route("/api/users/:id", get(get_user))
|
|
409
|
+
.with_state(state)
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### Diesel ORM Pattern
|
|
414
|
+
```rust
|
|
415
|
+
// Diesel database operations
|
|
416
|
+
use diesel::prelude::*;
|
|
417
|
+
|
|
418
|
+
pub struct UserRepository {
|
|
419
|
+
logger: DebugLogger,
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
impl UserRepository {
|
|
423
|
+
pub fn new() -> Self {
|
|
424
|
+
Self {
|
|
425
|
+
logger: DebugLogger::new("UserRepository"),
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
pub fn find_by_id(
|
|
430
|
+
&self,
|
|
431
|
+
conn: &mut PgConnection,
|
|
432
|
+
user_id: &str,
|
|
433
|
+
) -> Result<User, diesel::result::Error> {
|
|
434
|
+
let start = Instant::now();
|
|
435
|
+
self.logger.entry("find_by_id", &user_id);
|
|
436
|
+
|
|
437
|
+
let result = users::table
|
|
438
|
+
.filter(users::id.eq(user_id))
|
|
439
|
+
.first::<User>(conn);
|
|
440
|
+
|
|
441
|
+
match &result {
|
|
442
|
+
Ok(user) => {
|
|
443
|
+
self.logger.exit("find_by_id", user, start.elapsed().as_millis());
|
|
444
|
+
}
|
|
445
|
+
Err(e) => {
|
|
446
|
+
self.logger.error("find_by_id", e);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
result
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
## Error Handling Patterns
|
|
458
|
+
|
|
459
|
+
### Custom Error Types
|
|
460
|
+
```rust
|
|
461
|
+
// Comprehensive error handling with thiserror
|
|
462
|
+
use thiserror::Error;
|
|
463
|
+
|
|
464
|
+
#[derive(Error, Debug)]
|
|
465
|
+
pub enum ApplicationError {
|
|
466
|
+
#[error("Database error: {0}")]
|
|
467
|
+
Database(#[from] diesel::result::Error),
|
|
468
|
+
|
|
469
|
+
#[error("Validation error: {0}")]
|
|
470
|
+
Validation(#[from] ValidationError),
|
|
471
|
+
|
|
472
|
+
#[error("User not found: {0}")]
|
|
473
|
+
NotFound(String),
|
|
474
|
+
|
|
475
|
+
#[error("Internal server error: {0}")]
|
|
476
|
+
Internal(String),
|
|
477
|
+
|
|
478
|
+
#[error("Unauthorized: {0}")]
|
|
479
|
+
Unauthorized(String),
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
impl ApplicationError {
|
|
483
|
+
pub fn status_code(&self) -> StatusCode {
|
|
484
|
+
match self {
|
|
485
|
+
Self::Database(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
|
486
|
+
Self::Validation(_) => StatusCode::BAD_REQUEST,
|
|
487
|
+
Self::NotFound(_) => StatusCode::NOT_FOUND,
|
|
488
|
+
Self::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
|
489
|
+
Self::Unauthorized(_) => StatusCode::UNAUTHORIZED,
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### Result Type Patterns
|
|
496
|
+
```rust
|
|
497
|
+
// Use Result for error propagation
|
|
498
|
+
pub fn safe_operation() -> Result<String, ApplicationError> {
|
|
499
|
+
let value = risky_operation()?;
|
|
500
|
+
let processed = process_value(&value)?;
|
|
501
|
+
Ok(processed)
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// Custom Result alias
|
|
505
|
+
pub type AppResult<T> = Result<T, ApplicationError>;
|
|
506
|
+
|
|
507
|
+
pub fn get_user(id: &str) -> AppResult<User> {
|
|
508
|
+
validate_id(id)?;
|
|
509
|
+
let user = fetch_from_database(id)?;
|
|
510
|
+
Ok(user)
|
|
511
|
+
}
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
---
|
|
515
|
+
|
|
516
|
+
## Technology-Specific Command References
|
|
517
|
+
|
|
518
|
+
### Development Commands
|
|
519
|
+
```bash
|
|
520
|
+
# Rust Development
|
|
521
|
+
cargo run # Run application
|
|
522
|
+
cargo run --release # Run optimized build
|
|
523
|
+
cargo run --bin server # Run specific binary
|
|
524
|
+
cargo watch -x run # Auto-reload on changes
|
|
525
|
+
|
|
526
|
+
# Build Commands
|
|
527
|
+
cargo build # Debug build
|
|
528
|
+
cargo build --release # Production build
|
|
529
|
+
cargo check # Fast check without building
|
|
530
|
+
cargo clippy # Lint code
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
### Testing Commands
|
|
534
|
+
```bash
|
|
535
|
+
# Testing
|
|
536
|
+
cargo test # Run all tests
|
|
537
|
+
cargo test --lib # Library tests only
|
|
538
|
+
cargo test --test integration # Integration tests
|
|
539
|
+
cargo test -- --nocapture # Show println! output
|
|
540
|
+
cargo test --release # Test optimized build
|
|
541
|
+
|
|
542
|
+
# Coverage
|
|
543
|
+
cargo tarpaulin # Generate coverage (with tarpaulin)
|
|
544
|
+
cargo llvm-cov # Generate coverage (with llvm-cov)
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
### Documentation Commands
|
|
548
|
+
```bash
|
|
549
|
+
# Documentation
|
|
550
|
+
cargo doc # Generate documentation
|
|
551
|
+
cargo doc --open # Generate and open docs
|
|
552
|
+
cargo doc --no-deps # Only document this crate
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
|
|
557
|
+
## Trait System Best Practices
|
|
558
|
+
|
|
559
|
+
### Trait Design
|
|
560
|
+
```rust
|
|
561
|
+
// Design with traits for abstraction
|
|
562
|
+
pub trait Repository<T> {
|
|
563
|
+
fn find_by_id(&self, id: &str) -> AppResult<T>;
|
|
564
|
+
fn find_all(&self) -> AppResult<Vec<T>>;
|
|
565
|
+
fn save(&self, entity: &T) -> AppResult<T>;
|
|
566
|
+
fn delete(&self, id: &str) -> AppResult<()>;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Implement for specific types
|
|
570
|
+
impl Repository<User> for UserRepository {
|
|
571
|
+
fn find_by_id(&self, id: &str) -> AppResult<User> {
|
|
572
|
+
// Implementation
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
fn find_all(&self) -> AppResult<Vec<User>> {
|
|
576
|
+
// Implementation
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
fn save(&self, user: &User) -> AppResult<User> {
|
|
580
|
+
// Implementation
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
fn delete(&self, id: &str) -> AppResult<()> {
|
|
584
|
+
// Implementation
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
---
|
|
590
|
+
|
|
591
|
+
## Async/Await Patterns
|
|
592
|
+
|
|
593
|
+
### Tokio Async Runtime
|
|
594
|
+
```rust
|
|
595
|
+
// Async function with Tokio
|
|
596
|
+
use tokio::time::{sleep, Duration};
|
|
597
|
+
|
|
598
|
+
pub async fn fetch_user_async(user_id: &str) -> AppResult<User> {
|
|
599
|
+
let logger = DebugLogger::new("AsyncUserService");
|
|
600
|
+
let start = Instant::now();
|
|
601
|
+
logger.entry("fetch_user_async", &user_id);
|
|
602
|
+
|
|
603
|
+
// Async operation
|
|
604
|
+
sleep(Duration::from_millis(100)).await;
|
|
605
|
+
|
|
606
|
+
let user = User {
|
|
607
|
+
id: user_id.to_string(),
|
|
608
|
+
name: "John Doe".to_string(),
|
|
609
|
+
};
|
|
610
|
+
|
|
611
|
+
logger.exit("fetch_user_async", &user, start.elapsed().as_millis());
|
|
612
|
+
|
|
613
|
+
Ok(user)
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
// Spawn concurrent tasks
|
|
617
|
+
pub async fn fetch_multiple_users(user_ids: Vec<String>) -> Vec<AppResult<User>> {
|
|
618
|
+
let tasks: Vec<_> = user_ids
|
|
619
|
+
.into_iter()
|
|
620
|
+
.map(|id| tokio::spawn(fetch_user_async(id)))
|
|
621
|
+
.collect();
|
|
622
|
+
|
|
623
|
+
let results = futures::future::join_all(tasks).await;
|
|
624
|
+
|
|
625
|
+
results
|
|
626
|
+
.into_iter()
|
|
627
|
+
.map(|r| r.unwrap())
|
|
628
|
+
.collect()
|
|
629
|
+
}
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
---
|
|
633
|
+
|
|
634
|
+
## Reference to Parent Context
|
|
635
|
+
|
|
636
|
+
This file extends the Trinity Method protocols defined in `../trinity/CLAUDE.md` and global requirements from `../CLAUDE.md`. Rust implementations must comply with:
|
|
637
|
+
|
|
638
|
+
- Trinity Method investigation requirements ([../trinity/CLAUDE.md](../trinity/CLAUDE.md))
|
|
639
|
+
- Global performance baselines ([../trinity/knowledge-base/ARCHITECTURE.md](../trinity/knowledge-base/ARCHITECTURE.md#performance-baseline))
|
|
640
|
+
- Quality gate standards (BAS 6-phase) ([../trinity/CLAUDE.md](../trinity/CLAUDE.md#quality-standards))
|
|
641
|
+
- Crisis management protocols ([../trinity/CLAUDE.md](../trinity/CLAUDE.md#crisis-management))
|
|
642
|
+
|
|
643
|
+
All Rust code must implement the debugging frameworks, error handling patterns, and performance monitoring specified in this document.
|
|
644
|
+
|
|
645
|
+
---
|
|
646
|
+
|
|
647
|
+
**Technology Context**: Rust Implementation
|
|
648
|
+
**Parent References**:
|
|
649
|
+
- `../CLAUDE.md` - Global project requirements
|
|
650
|
+
- `../trinity/CLAUDE.md` - Trinity Method enforcement
|
|
651
|
+
|
|
652
|
+
**Last Updated**: {{CURRENT_DATE}}
|
|
653
|
+
**Trinity Version**: {{TRINITY_VERSION}}
|