ccjk 14.1.10 → 14.2.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.
Files changed (119) hide show
  1. package/dist/chunks/agent-teams.mjs +1 -1
  2. package/dist/chunks/api-cli.mjs +1 -1
  3. package/dist/chunks/api-config-selector.mjs +3 -3
  4. package/dist/chunks/ccjk-all.mjs +1 -1
  5. package/dist/chunks/ccjk-mcp.mjs +1 -1
  6. package/dist/chunks/ccjk-setup.mjs +1 -1
  7. package/dist/chunks/ccr.mjs +8 -8
  8. package/dist/chunks/check-updates.mjs +1 -1
  9. package/dist/chunks/claude-code-incremental-manager.mjs +3 -3
  10. package/dist/chunks/claude-config.mjs +1 -1
  11. package/dist/chunks/codex-config-switch.mjs +1 -1
  12. package/dist/chunks/codex-provider-manager.mjs +1 -1
  13. package/dist/chunks/config-switch.mjs +1 -1
  14. package/dist/chunks/config.mjs +19 -3
  15. package/dist/chunks/config2.mjs +1 -1
  16. package/dist/chunks/config3.mjs +1 -1
  17. package/dist/chunks/doctor.mjs +175 -6
  18. package/dist/chunks/features.mjs +3 -3
  19. package/dist/chunks/index10.mjs +19 -5
  20. package/dist/chunks/init.mjs +5 -5
  21. package/dist/chunks/mcp-cli.mjs +3 -3
  22. package/dist/chunks/mcp.mjs +3 -3
  23. package/dist/chunks/package.mjs +1 -1
  24. package/dist/chunks/quick-provider.mjs +1 -1
  25. package/dist/chunks/quick-setup.mjs +5 -5
  26. package/dist/chunks/simple-config.mjs +1 -1
  27. package/dist/chunks/smart-guide.mjs +1 -1
  28. package/dist/chunks/update.mjs +6 -6
  29. package/dist/chunks/zero-config.mjs +7 -4
  30. package/dist/cli.mjs +0 -0
  31. package/dist/index.d.mts +3 -0
  32. package/dist/index.d.ts +3 -0
  33. package/dist/index.mjs +1 -1
  34. package/dist/shared/{ccjk.BJ3Zpjo5.mjs → ccjk.BCzOWT1L.mjs} +3 -2
  35. package/dist/shared/{ccjk.B8oqkakg.mjs → ccjk.BLsIiTqO.mjs} +1 -1
  36. package/dist/shared/{ccjk.Hwoicrh8.mjs → ccjk.BXv8aYs1.mjs} +1 -1
  37. package/dist/shared/{ccjk.B9OuS4xZ.mjs → ccjk.CfKJnpbB.mjs} +1 -1
  38. package/dist/shared/{ccjk.BzxpiEPF.mjs → ccjk.Cgv_cFVX.mjs} +2 -2
  39. package/dist/shared/{ccjk.Di1IYU3u.mjs → ccjk.DDL-4C-k.mjs} +47 -10
  40. package/dist/shared/{ccjk.BEiR3L4C.mjs → ccjk.DOw7Fawt.mjs} +3 -3
  41. package/dist/shared/{ccjk.tI_s2uSh.mjs → ccjk.f3TBLJSt.mjs} +1 -1
  42. package/dist/templates/agents/README.md +78 -0
  43. package/dist/templates/common/error-prevention.md +267 -0
  44. package/dist/templates/common/karpathy-baseline.md +83 -0
  45. package/dist/templates/common/output-styles/zh-CN/carmack-mode.md +381 -0
  46. package/dist/templates/common/output-styles/zh-CN/dhh-mode.md +265 -0
  47. package/dist/templates/common/output-styles/zh-CN/evan-you-mode.md +539 -0
  48. package/dist/templates/common/output-styles/zh-CN/jobs-mode.md +369 -0
  49. package/dist/templates/common/output-styles/zh-CN/linus-mode.md +135 -0
  50. package/dist/templates/common/output-styles/zh-CN/uncle-bob-mode.md +221 -0
  51. package/dist/templates/common/workflow/continuousDelivery/en/continuous-delivery.md +628 -0
  52. package/dist/templates/common/workflow/continuousDelivery/zh-CN/continuous-delivery.md +628 -0
  53. package/dist/templates/common/workflow/essential/en/agents/ccjk-config-agent.md +187 -0
  54. package/dist/templates/common/workflow/essential/en/agents/ccjk-mcp-agent.md +191 -0
  55. package/dist/templates/common/workflow/essential/en/agents/ccjk-skill-agent.md +249 -0
  56. package/dist/templates/common/workflow/essential/en/agents/ccjk-workflow-agent.md +277 -0
  57. package/dist/templates/common/workflow/essential/en/agents/get-current-datetime.md +29 -0
  58. package/dist/templates/common/workflow/essential/en/agents/init-architect.md +115 -0
  59. package/dist/templates/common/workflow/essential/en/agents/ui-ux-designer.md +91 -0
  60. package/dist/templates/common/workflow/essential/en/feat.md +92 -0
  61. package/dist/templates/common/workflow/essential/en/goal.md +147 -0
  62. package/dist/templates/common/workflow/essential/en/init-project.md +53 -0
  63. package/dist/templates/common/workflow/essential/zh-CN/agents/get-current-datetime.md +29 -0
  64. package/dist/templates/common/workflow/essential/zh-CN/agents/init-architect.md +115 -0
  65. package/dist/templates/common/workflow/essential/zh-CN/agents/ui-ux-designer.md +91 -0
  66. package/dist/templates/common/workflow/essential/zh-CN/feat.md +315 -0
  67. package/dist/templates/common/workflow/essential/zh-CN/goal.md +146 -0
  68. package/dist/templates/common/workflow/essential/zh-CN/init-project.md +53 -0
  69. package/dist/templates/common/workflow/git/en/git-cleanBranches.md +102 -0
  70. package/dist/templates/common/workflow/git/en/git-commit.md +205 -0
  71. package/dist/templates/common/workflow/git/en/git-rollback.md +90 -0
  72. package/dist/templates/common/workflow/git/en/git-worktree.md +276 -0
  73. package/dist/templates/common/workflow/git/zh-CN/git-cleanBranches.md +102 -0
  74. package/dist/templates/common/workflow/git/zh-CN/git-commit.md +205 -0
  75. package/dist/templates/common/workflow/git/zh-CN/git-rollback.md +90 -0
  76. package/dist/templates/common/workflow/git/zh-CN/git-worktree.md +276 -0
  77. package/dist/templates/common/workflow/interview/en/interview.md +67 -0
  78. package/dist/templates/common/workflow/interview/zh-CN/interview.md +67 -0
  79. package/dist/templates/common/workflow/linearMethod/en/linear-method.md +651 -0
  80. package/dist/templates/common/workflow/linearMethod/zh-CN/linear-method.md +752 -0
  81. package/dist/templates/common/workflow/refactoringMaster/en/refactoring-master.md +516 -0
  82. package/dist/templates/common/workflow/refactoringMaster/zh-CN/refactoring-master.md +812 -0
  83. package/dist/templates/common/workflow/sixStep/en/workflow.md +83 -0
  84. package/dist/templates/common/workflow/sixStep/zh-CN/workflow.md +359 -0
  85. package/dist/templates/common/workflow/specFirstTDD/en/spec-first-tdd.md +364 -0
  86. package/dist/templates/common/workflow/specFirstTDD/zh-CN/spec-first-tdd.md +366 -0
  87. package/dist/templates/hooks/README.md +212 -0
  88. package/dist/templates/hooks/git-workflow-hooks.md +551 -0
  89. package/dist/templates/hooks/post-test-coverage.md +434 -0
  90. package/dist/templates/hooks/pre-commit-black.md +274 -0
  91. package/dist/templates/hooks/pre-commit-eslint.md +153 -0
  92. package/dist/templates/hooks/pre-commit-gofmt.md +284 -0
  93. package/dist/templates/hooks/pre-commit-prettier.md +212 -0
  94. package/dist/templates/hooks/pre-commit-type-check.md +377 -0
  95. package/dist/templates/skills/ccjk-init.md +154 -0
  96. package/dist/templates/skills/ccjk-mcp-setup.md +205 -0
  97. package/dist/templates/skills/ccjk-troubleshoot.md +228 -0
  98. package/dist/templates/skills/django-patterns.md +1016 -0
  99. package/dist/templates/skills/git-workflow.md +748 -0
  100. package/dist/templates/skills/go-idioms.md +963 -0
  101. package/dist/templates/skills/nextjs-optimization.md +694 -0
  102. package/dist/templates/skills/python-pep8.md +852 -0
  103. package/dist/templates/skills/react-patterns.md +686 -0
  104. package/dist/templates/skills/rust-patterns.md +1057 -0
  105. package/dist/templates/skills/security-best-practices.md +1413 -0
  106. package/dist/templates/skills/testing-best-practices.md +1315 -0
  107. package/dist/templates/skills/ts-best-practices.md +354 -0
  108. package/package.json +40 -43
  109. package/templates/common/karpathy-baseline.md +83 -0
  110. package/templates/common/output-styles/zh-CN/carmack-mode.md +14 -0
  111. package/templates/common/output-styles/zh-CN/dhh-mode.md +14 -0
  112. package/templates/common/output-styles/zh-CN/evan-you-mode.md +14 -0
  113. package/templates/common/output-styles/zh-CN/jobs-mode.md +14 -0
  114. package/templates/common/output-styles/zh-CN/linus-mode.md +14 -0
  115. package/templates/common/output-styles/zh-CN/uncle-bob-mode.md +14 -0
  116. package/templates/common/workflow/linearMethod/zh-CN/linear-method.md +2 -0
  117. package/templates/common/workflow/refactoringMaster/zh-CN/refactoring-master.md +2 -0
  118. package/templates/common/workflow/sixStep/zh-CN/workflow.md +2 -0
  119. package/templates/common/workflow/specFirstTDD/zh-CN/spec-first-tdd.md +2 -0
@@ -0,0 +1,1057 @@
1
+ ---
2
+ name: rust-patterns
3
+ description: Rust ownership patterns, borrow checker, lifetime annotations, and async/await
4
+ description_zh: Rust 所有权模式、借用检查器、生命周期注解和 async/await
5
+ version: 1.0.0
6
+ category: programming
7
+ triggers: ['/rust-patterns', '/rust', '/ownership', '/lifetimes', '/async-rust']
8
+ use_when:
9
+ - Writing safe and efficient Rust code with proper ownership
10
+ - Implementing async/await patterns and concurrent programming
11
+ - Working with lifetimes and borrow checker
12
+ - Code review for Rust projects
13
+ use_when_zh:
14
+ - 编写具有适当所有权的安全高效 Rust 代码
15
+ - 实现 async/await 模式和并发编程
16
+ - 使用生命周期和借用检查器
17
+ - Rust 项目代码审查
18
+ auto_activate: true
19
+ priority: 8
20
+ agents: [rust-expert, systems-programmer]
21
+ tags: [rust, ownership, lifetimes, async, safety, performance]
22
+ ---
23
+
24
+ # Rust Patterns | Rust 模式
25
+
26
+ ## Context | 上下文
27
+
28
+ Use this skill when writing Rust code that leverages ownership, borrowing, and lifetimes for memory safety without garbage collection. Essential for systems programming and high-performance applications.
29
+
30
+ 在编写利用所有权、借用和生命周期实现内存安全而无需垃圾回收的 Rust 代码时使用此技能。对于系统编程和高性能应用程序至关重要。
31
+
32
+ ## Ownership and Borrowing | 所有权和借用
33
+
34
+ ### 1. Ownership Patterns | 所有权模式
35
+
36
+ ```rust
37
+ use std::collections::HashMap;
38
+
39
+ // ✅ Good: Clear ownership patterns
40
+
41
+ #[derive(Debug, Clone)]
42
+ pub struct User {
43
+ pub id: u64,
44
+ pub name: String,
45
+ pub email: String,
46
+ }
47
+
48
+ impl User {
49
+ pub fn new(id: u64, name: String, email: String) -> Self {
50
+ Self { id, name, email }
51
+ }
52
+
53
+ // Taking ownership when we need to consume the value
54
+ pub fn into_summary(self) -> String {
55
+ format!("{} ({})", self.name, self.email)
56
+ }
57
+
58
+ // Borrowing immutably when we only need to read
59
+ pub fn display_info(&self) -> String {
60
+ format!("User {}: {} <{}>", self.id, self.name, self.email)
61
+ }
62
+
63
+ // Borrowing mutably when we need to modify
64
+ pub fn update_email(&mut self, new_email: String) -> Result<(), &'static str> {
65
+ if new_email.contains('@') {
66
+ self.email = new_email;
67
+ Ok(())
68
+ } else {
69
+ Err("Invalid email format")
70
+ }
71
+ }
72
+ }
73
+
74
+ // ✅ Good: Repository pattern with proper ownership
75
+ pub struct UserRepository {
76
+ users: HashMap<u64, User>,
77
+ next_id: u64,
78
+ }
79
+
80
+ impl UserRepository {
81
+ pub fn new() -> Self {
82
+ Self {
83
+ users: HashMap::new(),
84
+ next_id: 1,
85
+ }
86
+ }
87
+
88
+ // Taking ownership of the user data
89
+ pub fn create_user(&mut self, name: String, email: String) -> u64 {
90
+ let id = self.next_id;
91
+ self.next_id += 1;
92
+
93
+ let user = User::new(id, name, email);
94
+ self.users.insert(id, user);
95
+
96
+ id
97
+ }
98
+
99
+ // Returning a reference to avoid unnecessary cloning
100
+ pub fn get_user(&self, id: u64) -> Option<&User> {
101
+ self.users.get(&id)
102
+ }
103
+
104
+ // Returning a mutable reference for in-place updates
105
+ pub fn get_user_mut(&mut self, id: u64) -> Option<&mut User> {
106
+ self.users.get_mut(&id)
107
+ }
108
+
109
+ // Taking ownership when removing
110
+ pub fn remove_user(&mut self, id: u64) -> Option<User> {
111
+ self.users.remove(&id)
112
+ }
113
+
114
+ // Returning an iterator over references
115
+ pub fn all_users(&self) -> impl Iterator<Item = &User> {
116
+ self.users.values()
117
+ }
118
+
119
+ // Method that consumes self and returns owned data
120
+ pub fn into_users(self) -> Vec<User> {
121
+ self.users.into_values().collect()
122
+ }
123
+ }
124
+
125
+ // ✅ Good: Builder pattern with ownership transfer
126
+ pub struct UserBuilder {
127
+ name: Option<String>,
128
+ email: Option<String>,
129
+ }
130
+
131
+ impl UserBuilder {
132
+ pub fn new() -> Self {
133
+ Self {
134
+ name: None,
135
+ email: None,
136
+ }
137
+ }
138
+
139
+ // Taking ownership of self and returning it (fluent interface)
140
+ pub fn name(mut self, name: String) -> Self {
141
+ self.name = Some(name);
142
+ self
143
+ }
144
+
145
+ pub fn email(mut self, email: String) -> Self {
146
+ self.email = Some(email);
147
+ self
148
+ }
149
+
150
+ // Consuming self to build the final object
151
+ pub fn build(self, id: u64) -> Result<User, &'static str> {
152
+ let name = self.name.ok_or("Name is required")?;
153
+ let email = self.email.ok_or("Email is required")?;
154
+
155
+ Ok(User::new(id, name, email))
156
+ }
157
+ }
158
+
159
+ // Usage examples
160
+ fn ownership_examples() {
161
+ let mut repo = UserRepository::new();
162
+
163
+ // Create user - strings are moved into the method
164
+ let user_id = repo.create_user("Alice".to_string(), "alice@example.com".to_string());
165
+
166
+ // Borrow user immutably
167
+ if let Some(user) = repo.get_user(user_id) {
168
+ println!("{}", user.display_info());
169
+ }
170
+
171
+ // Borrow user mutably
172
+ if let Some(user) = repo.get_user_mut(user_id) {
173
+ let _ = user.update_email("alice.new@example.com".to_string());
174
+ }
175
+
176
+ // Builder pattern
177
+ let user = UserBuilder::new()
178
+ .name("Bob".to_string())
179
+ .email("bob@example.com".to_string())
180
+ .build(2)
181
+ .expect("Failed to build user");
182
+
183
+ println!("{}", user.into_summary()); // user is consumed here
184
+ }
185
+
186
+ // ❌ Bad: Unclear ownership and unnecessary cloning
187
+ fn bad_ownership_example() {
188
+ let user = User::new(1, "Alice".to_string(), "alice@example.com".to_string());
189
+
190
+ // Unnecessary clone
191
+ let user_copy = user.clone();
192
+ println!("{}", user_copy.display_info());
193
+
194
+ // Could have just borrowed
195
+ println!("{}", user.display_info());
196
+ }
197
+ ```
198
+
199
+ ### 2. Smart Pointers | 智能指针
200
+
201
+ ```rust
202
+ use std::rc::{Rc, Weak};
203
+ use std::cell::{RefCell, Cell};
204
+ use std::sync::{Arc, Mutex, RwLock};
205
+ use std::thread;
206
+
207
+ // ✅ Good: Using Rc for shared ownership (single-threaded)
208
+ #[derive(Debug)]
209
+ struct Node {
210
+ value: i32,
211
+ children: Vec<Rc<Node>>,
212
+ parent: Option<Weak<Node>>,
213
+ }
214
+
215
+ impl Node {
216
+ fn new(value: i32) -> Rc<Self> {
217
+ Rc::new(Node {
218
+ value,
219
+ children: Vec::new(),
220
+ parent: None,
221
+ })
222
+ }
223
+
224
+ fn add_child(parent: &Rc<Node>, child: Rc<Node>) {
225
+ // This would require RefCell for interior mutability in practice
226
+ // Simplified for demonstration
227
+ }
228
+ }
229
+
230
+ // ✅ Good: Using RefCell for interior mutability
231
+ struct Counter {
232
+ value: RefCell<i32>,
233
+ }
234
+
235
+ impl Counter {
236
+ fn new() -> Self {
237
+ Self {
238
+ value: RefCell::new(0),
239
+ }
240
+ }
241
+
242
+ fn increment(&self) {
243
+ let mut value = self.value.borrow_mut();
244
+ *value += 1;
245
+ }
246
+
247
+ fn get(&self) -> i32 {
248
+ *self.value.borrow()
249
+ }
250
+ }
251
+
252
+ // ✅ Good: Using Arc and Mutex for thread-safe shared state
253
+ #[derive(Clone)]
254
+ struct ThreadSafeCounter {
255
+ value: Arc<Mutex<i32>>,
256
+ }
257
+
258
+ impl ThreadSafeCounter {
259
+ fn new() -> Self {
260
+ Self {
261
+ value: Arc::new(Mutex::new(0)),
262
+ }
263
+ }
264
+
265
+ fn increment(&self) {
266
+ let mut value = self.value.lock().unwrap();
267
+ *value += 1;
268
+ }
269
+
270
+ fn get(&self) -> i32 {
271
+ *self.value.lock().unwrap()
272
+ }
273
+ }
274
+
275
+ // ✅ Good: Using RwLock for read-heavy workloads
276
+ struct ReadHeavyData {
277
+ data: Arc<RwLock<HashMap<String, String>>>,
278
+ }
279
+
280
+ impl ReadHeavyData {
281
+ fn new() -> Self {
282
+ Self {
283
+ data: Arc::new(RwLock::new(HashMap::new())),
284
+ }
285
+ }
286
+
287
+ fn get(&self, key: &str) -> Option<String> {
288
+ let data = self.data.read().unwrap();
289
+ data.get(key).cloned()
290
+ }
291
+
292
+ fn insert(&self, key: String, value: String) {
293
+ let mut data = self.data.write().unwrap();
294
+ data.insert(key, value);
295
+ }
296
+ }
297
+
298
+ // Usage with threads
299
+ fn smart_pointer_examples() {
300
+ // Single-threaded reference counting
301
+ let counter = Counter::new();
302
+ counter.increment();
303
+ println!("Counter: ", counter.get());
304
+
305
+ // Multi-threaded shared state
306
+ let thread_safe_counter = ThreadSafeCounter::new();
307
+ let mut handles = vec![];
308
+
309
+ for _ in 0..10 {
310
+ let counter = thread_safe_counter.clone();
311
+ let handle = thread::spawn(move || {
312
+ for _ in 0..100 {
313
+ counter.increment();
314
+ }
315
+ });
316
+ handles.push(handle);
317
+ }
318
+
319
+ for handle in handles {
320
+ handle.join().unwrap();
321
+ }
322
+
323
+ println!("Final count: {}", thread_safe_counter.get());
324
+ }
325
+ ```
326
+
327
+ ## Lifetimes and Borrowing | 生命周期和借用
328
+
329
+ ### 1. Lifetime Annotations | 生命周期注解
330
+
331
+ ```rust
332
+ // ✅ Good: Proper lifetime annotations
333
+
334
+ // Simple lifetime parameter
335
+ fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
336
+ if x.len() > y.len() {
337
+ x
338
+ } else {
339
+ y
340
+ }
341
+ }
342
+
343
+ // Multiple lifetime parameters
344
+ fn first_word<'a, 'b>(s: &'a str, _delimiter: &'b str) -> &'a str {
345
+ s.split_whitespace().next().unwrap_or("")
346
+ }
347
+
348
+ // Struct with lifetime parameters
349
+ #[derive(Debug)]
350
+ struct TextProcessor<'a> {
351
+ text: &'a str,
352
+ processed: Vec<&'a str>,
353
+ }
354
+
355
+ impl<'a> TextProcessor<'a> {
356
+ fn new(text: &'a str) -> Self {
357
+ Self {
358
+ text,
359
+ processed: Vec::new(),
360
+ }
361
+ }
362
+
363
+ fn process_words(&mut self) {
364
+ self.processed = self.text
365
+ .split_whitespace()
366
+ .filter(|word| word.len() > 3)
367
+ .collect();
368
+ }
369
+
370
+ fn get_processed(&self) -> &[&'a str] {
371
+ &self.processed
372
+ }
373
+
374
+ // Method with additional lifetime parameter
375
+ fn find_in_text<'b>(&self, pattern: &'b str) -> Option<&'a str> {
376
+ self.text
377
+ .split_whitespace()
378
+ .find(|word| word.contains(pattern))
379
+ }
380
+ }
381
+
382
+ // ✅ Good: Lifetime elision rules
383
+ // These functions don't need explicit lifetime annotations
384
+
385
+ // Rule 1: Each parameter gets its own lifetime
386
+ fn process_string(s: &str) -> String {
387
+ s.to_uppercase()
388
+ }
389
+
390
+ // Rule 2: If there's exactly one input lifetime, it's assigned to all outputs
391
+ fn get_first_char(s: &str) -> Option<&str> {
392
+ s.chars().next().map(|_| &s[0..1])
393
+ }
394
+
395
+ // Rule 3: If one parameter is &self or &mut self, its lifetime is assigned to all outputs
396
+ impl<'a> TextProcessor<'a> {
397
+ fn get_text(&self) -> &str {
398
+ self.text
399
+ }
400
+
401
+ fn get_first_processed(&self) -> Option<&str> {
402
+ self.processed.first().copied()
403
+ }
404
+ }
405
+
406
+ // ✅ Good: Static lifetime for string literals and global data
407
+ static GLOBAL_CONFIG: &str = "production";
408
+
409
+ fn get_config() -> &'static str {
410
+ GLOBAL_CONFIG
411
+ }
412
+
413
+ // Function that returns a string literal (has 'static lifetime)
414
+ fn get_error_message() -> &'static str {
415
+ "An error occurred"
416
+ }
417
+
418
+ // ✅ Good: Lifetime bounds in generics
419
+ fn process_and_store<'a, T>(data: &'a T, storage: &mut Vec<&'a T>)
420
+ where
421
+ T: std::fmt::Debug + 'a,
422
+ {
423
+ println!("Processing: {:?}", data);
424
+ storage.push(data);
425
+ }
426
+
427
+ // Higher-ranked trait bounds (HRTB)
428
+ fn apply_to_all<F>(strings: &[String], f: F)
429
+ where
430
+ F: for<'a> Fn(&'a str) -> &'a str,
431
+ {
432
+ for s in strings {
433
+ let result = f(s);
434
+ println!("{}", result);
435
+ }
436
+ }
437
+
438
+ // Usage examples
439
+ fn lifetime_examples() {
440
+ let text1 = "Hello world";
441
+ let text2 = "Hi";
442
+
443
+ let longer = longest(text1, text2);
444
+ println!("Longer: {}", longer);
445
+
446
+ let mut processor = TextProcessor::new("This is a sample text with some words");
447
+ processor.process_words();
448
+
449
+ for word in processor.get_processed() {
450
+ println!("Processed word: {}", word);
451
+ }
452
+
453
+ if let Some(found) = processor.find_in_text("sample") {
454
+ println!("Found word containing 'sample': {}", found);
455
+ }
456
+ }
457
+ ```
458
+
459
+ ### 2. Advanced Borrowing Patterns | 高级借用模式
460
+
461
+ ```rust
462
+ use std::collections::HashMap;
463
+
464
+ // ✅ Good: Splitting borrows
465
+ struct Database {
466
+ users: HashMap<u64, User>,
467
+ sessions: HashMap<String, u64>,
468
+ }
469
+
470
+ impl Database {
471
+ fn new() -> Self {
472
+ Self {
473
+ users: HashMap::new(),
474
+ sessions: HashMap::new(),
475
+ }
476
+ }
477
+
478
+ // Split mutable borrows to avoid conflicts
479
+ fn get_users_and_sessions_mut(&mut self) -> (&mut HashMap<u64, User>, &mut HashMap<String, u64>) {
480
+ (&mut self.users, &mut self.sessions)
481
+ }
482
+
483
+ // Method that needs to borrow different parts
484
+ fn authenticate_and_update(&mut self, session_id: &str, new_email: String) -> Result<(), &'static str> {
485
+ // First, get the user ID from session
486
+ let user_id = self.sessions.get(session_id)
487
+ .copied()
488
+ .ok_or("Invalid session")?;
489
+
490
+ // Then update the user - this works because we're not holding a reference to sessions
491
+ let user = self.users.get_mut(&user_id)
492
+ .ok_or("User not found")?;
493
+
494
+ user.update_email(new_email)?;
495
+
496
+ Ok(())
497
+ }
498
+ }
499
+
500
+ // ✅ Good: Using entry API to avoid double lookups
501
+ impl Database {
502
+ fn get_or_create_user(&mut self, id: u64, name: String, email: String) -> &mut User {
503
+ self.users.entry(id).or_insert_with(|| User::new(id, name, email))
504
+ }
505
+
506
+ fn update_or_create_session(&mut self, session_id: String, user_id: u64) {
507
+ self.sessions.insert(session_id, user_id);
508
+ }
509
+ }
510
+
511
+ // ✅ Good: Iterator patterns that work with borrowing
512
+ impl Database {
513
+ fn find_users_by_email_domain(&self, domain: &str) -> impl Iterator<Item = &User> {
514
+ self.users.values()
515
+ .filter(move |user| user.email.ends_with(domain))
516
+ }
517
+
518
+ fn active_sessions(&self) -> impl Iterator<Item = (&String, &u64)> {
519
+ self.sessions.iter()
520
+ }
521
+ }
522
+
523
+ // ✅ Good: Avoiding borrowing issues with cloning when necessary
524
+ #[derive(Debug, Clone)]
525
+ struct UserSummary {
526
+ id: u64,
527
+ name: String,
528
+ email_domain: String,
529
+ }
530
+
531
+ impl Database {
532
+ fn get_user_summaries(&self) -> Vec<UserSummary> {
533
+ self.users.values()
534
+ .map(|user| UserSummary {
535
+ id: user.id,
536
+ name: user.name.clone(),
537
+ email_domain: user.email.split('@').nth(1).unwrap_or("").to_string(),
538
+ })
539
+ .collect()
540
+ }
541
+ }
542
+
543
+ // ✅ Good: Using Cow (Clone on Write) for efficiency
544
+ use std::borrow::Cow;
545
+
546
+ fn process_text(text: &str) -> Cow<str> {
547
+ if text.contains("bad_word") {
548
+ // Only clone/allocate if we need to modify
549
+ Cow::Owned(text.replace("bad_word", "***"))
550
+ } else {
551
+ // Return borrowed data if no modification needed
552
+ Cow::Borrowed(text)
553
+ }
554
+ }
555
+
556
+ fn cow_example() {
557
+ let clean_text = "This is clean text";
558
+ let dirty_text = "This contains bad_word";
559
+
560
+ let result1 = process_text(clean_text); // No allocation
561
+ let result2 = process_text(dirty_text); // Allocates new string
562
+
563
+ println!("Result 1: {}", result1);
564
+ println!("Result 2: {}", result2);
565
+ }
566
+ ```
567
+
568
+ ## Async/Await Patterns | Async/Await 模式
569
+
570
+ ### 1. Basic Async Patterns | 基本异步模式
571
+
572
+ ```rust
573
+ use tokio;
574
+ use std::time::Duration;
575
+ use futures::future::{join, join_all, select, Either};
576
+
577
+ // ✅ Good: Basic async function
578
+ async fn fetch_user_data(user_id: u64) -> Result<User, Box<dyn std::error::Error>> {
579
+ // Simulate network delay
580
+ tokio::time::sleep(Duration::from_millis(100)).await;
581
+
582
+ // Simulate fetching from database
583
+ Ok(User::new(user_id, "Alice".to_string(), "alice@example.com".to_string()))
584
+ }
585
+
586
+ // ✅ Good: Async method in impl block
587
+ struct UserService {
588
+ base_url: String,
589
+ }
590
+
591
+ impl UserService {
592
+ fn new(base_url: String) -> Self {
593
+ Self { base_url }
594
+ }
595
+
596
+ async fn get_user(&self, id: u64) -> Result<User, Box<dyn std::error::Error>> {
597
+ let url = format!("{}/users/{}", self.base_url, id);
598
+
599
+ // Simulate HTTP request
600
+ tokio::time::sleep(Duration::from_millis(50)).await;
601
+
602
+ fetch_user_data(id).await
603
+ }
604
+
605
+ async fn create_user(&self, name: String, email: String) -> Result<User, Box<dyn std::error::Error>> {
606
+ // Simulate validation
607
+ if name.is_empty() || email.is_empty() {
608
+ return Err("Name and email are required".into());
609
+ }
610
+
611
+ // Simulate HTTP POST
612
+ tokio::time::sleep(Duration::from_millis(200)).await;
613
+
614
+ Ok(User::new(1, name, email))
615
+ }
616
+ }
617
+
618
+ // ✅ Good: Concurrent execution with join
619
+ async fn fetch_multiple_users(ids: Vec<u64>) -> Vec<Result<User, Box<dyn std::error::Error>>> {
620
+ let futures: Vec<_> = ids.into_iter()
621
+ .map(|id| fetch_user_data(id))
622
+ .collect();
623
+
624
+ join_all(futures).await
625
+ }
626
+
627
+ // ✅ Good: Racing futures with select
628
+ async fn fetch_with_timeout(user_id: u64) -> Result<User, &'static str> {
629
+ let fetch_future = fetch_user_data(user_id);
630
+ let timeout_future = tokio::time::sleep(Duration::from_secs(5));
631
+
632
+ match select(fetch_future, timeout_future).await {
633
+ Either::Left((result, _)) => result.map_err(|_| "Fetch failed"),
634
+ Either::Right((_, _)) => Err("Timeout"),
635
+ }
636
+ }
637
+
638
+ // ✅ Good: Async iterator pattern
639
+ use futures::stream::{self, StreamExt};
640
+
641
+ async fn process_users_stream(user_ids: Vec<u64>) {
642
+ let user_stream = stream::iter(user_ids)
643
+ .map(|id| async move {
644
+ fetch_user_data(id).await
645
+ })
646
+ .buffer_unordered(5); // Process up to 5 concurrently
647
+
648
+ user_stream
649
+ .for_each(|result| async {
650
+ match result {
651
+ Ok(user) => println!("Processed user: {}", user.display_info()),
652
+ Err(e) => eprintln!("Error processing user: {}", e),
653
+ }
654
+ })
655
+ .await;
656
+ }
657
+
658
+ #[tokio::main]
659
+ async fn main() -> Result<(), Box<dyn std::error::Error>> {
660
+ let service = UserService::new("https://api.example.com".to_string());
661
+
662
+ // Sequential execution
663
+ let user1 = service.get_user(1).await?;
664
+ println!("User 1: {}", user1.display_info());
665
+
666
+ // Concurrent execution
667
+ let (user2_result, user3_result) = join(
668
+ service.get_user(2),
669
+ service.get_user(3)
670
+ ).await;
671
+
672
+ if let Ok(user2) = user2_result {
673
+ println!("User 2: {}", user2.display_info());
674
+ }
675
+
676
+ if let Ok(user3) = user3_result {
677
+ println!("User 3: {}", user3.display_info());
678
+ }
679
+
680
+ // Fetch multiple users concurrently
681
+ let user_ids = vec![4, 5, 6, 7, 8];
682
+ let results = fetch_multiple_users(user_ids).await;
683
+
684
+ for (i, result) in results.into_iter().enumerate() {
685
+ match result {
686
+ Ok(user) => println!("User {}: {}", i + 4, user.display_info()),
687
+ Err(e) => eprintln!("Error fetching user {}: {}", i + 4, e),
688
+ }
689
+ }
690
+
691
+ // Process users with streaming
692
+ let stream_ids = vec![9, 10, 11, 12, 13];
693
+ process_users_stream(stream_ids).await;
694
+
695
+ Ok(())
696
+ }
697
+ ```
698
+
699
+ ### 2. Advanced Async Patterns | 高级异步模式
700
+
701
+ ```rust
702
+ use tokio::sync::{mpsc, oneshot, Mutex, RwLock};
703
+ use std::sync::Arc;
704
+ use std::collections::HashMap;
705
+
706
+ // ✅ Good: Actor pattern with message passing
707
+ #[derive(Debug)]
708
+ enum UserMessage {
709
+ Get { id: u64, respond_to: oneshot::Sender<Option<User>> },
710
+ Create { user: User, respond_to: oneshot::Sender<Result<(), String>> },
711
+ Update { id: u64, email: String, respond_to: oneshot::Sender<Result<(), String>> },
712
+ }
713
+
714
+ struct UserActor {
715
+ receiver: mpsc::Receiver<UserMessage>,
716
+ users: HashMap<u64, User>,
717
+ }
718
+
719
+ impl UserActor {
720
+ fn new(receiver: mpsc::Receiver<UserMessage>) -> Self {
721
+ Self {
722
+ receiver,
723
+ users: HashMap::new(),
724
+ }
725
+ }
726
+
727
+ async fn run(&mut self) {
728
+ while let Some(msg) = self.receiver.recv().await {
729
+ match msg {
730
+ UserMessage::Get { id, respond_to } => {
731
+ let user = self.users.get(&id).cloned();
732
+ let _ = respond_to.send(user);
733
+ }
734
+ UserMessage::Create { user, respond_to } => {
735
+ let id = user.id;
736
+ self.users.insert(id, user);
737
+ let _ = respond_to.send(Ok(()));
738
+ }
739
+ UserMessage::Update { id, email, respond_to } => {
740
+ if let Some(user) = self.users.get_mut(&id) {
741
+ match user.update_email(email) {
742
+ Ok(()) => { let _ = respond_to.send(Ok(())); }
743
+ Err(e) => { let _ = respond_to.send(Err(e.to_string())); }
744
+ }
745
+ } else {
746
+ let _ = respond_to.send(Err("User not found".to_string()));
747
+ }
748
+ }
749
+ }
750
+ }
751
+ }
752
+ }
753
+
754
+ // Handle for communicating with the actor
755
+ #[derive(Clone)]
756
+ struct UserActorHandle {
757
+ sender: mpsc::Sender<UserMessage>,
758
+ }
759
+
760
+ impl UserActorHandle {
761
+ fn new() -> Self {
762
+ let (sender, receiver) = mpsc::channel(100);
763
+ let mut actor = UserActor::new(receiver);
764
+
765
+ tokio::spawn(async move {
766
+ actor.run().await;
767
+ });
768
+
769
+ Self { sender }
770
+ }
771
+
772
+ async fn get_user(&self, id: u64) -> Option<User> {
773
+ let (send, recv) = oneshot::channel();
774
+ let msg = UserMessage::Get { id, respond_to: send };
775
+
776
+ if self.sender.send(msg).await.is_ok() {
777
+ recv.await.unwrap_or(None)
778
+ } else {
779
+ None
780
+ }
781
+ }
782
+
783
+ async fn create_user(&self, user: User) -> Result<(), String> {
784
+ let (send, recv) = oneshot::channel();
785
+ let msg = UserMessage::Create { user, respond_to: send };
786
+
787
+ if self.sender.send(msg).await.is_ok() {
788
+ recv.await.unwrap_or(Err("Actor unavailable".to_string()))
789
+ } else {
790
+ Err("Failed to send message".to_string())
791
+ }
792
+ }
793
+ }
794
+
795
+ // ✅ Good: Shared state with async locks
796
+ #[derive(Clone)]
797
+ struct AsyncUserRepository {
798
+ users: Arc<RwLock<HashMap<u64, User>>>,
799
+ next_id: Arc<Mutex<u64>>,
800
+ }
801
+
802
+ impl AsyncUserRepository {
803
+ fn new() -> Self {
804
+ Self {
805
+ users: Arc::new(RwLock::new(HashMap::new())),
806
+ next_id: Arc::new(Mutex::new(1)),
807
+ }
808
+ }
809
+
810
+ async fn create_user(&self, name: String, email: String) -> u64 {
811
+ let mut next_id = self.next_id.lock().await;
812
+ let id = *next_id;
813
+ *next_id += 1;
814
+ drop(next_id); // Release lock early
815
+
816
+ let user = User::new(id, name, email);
817
+ let mut users = self.users.write().await;
818
+ users.insert(id, user);
819
+
820
+ id
821
+ }
822
+
823
+ async fn get_user(&self, id: u64) -> Option<User> {
824
+ let users = self.users.read().await;
825
+ users.get(&id).cloned()
826
+ }
827
+
828
+ async fn update_user_email(&self, id: u64, new_email: String) -> Result<(), String> {
829
+ let mut users = self.users.write().await;
830
+ if let Some(user) = users.get_mut(&id) {
831
+ user.update_email(new_email).map_err(|e| e.to_string())
832
+ } else {
833
+ Err("User not found".to_string())
834
+ }
835
+ }
836
+ }
837
+
838
+ // ✅ Good: Background task pattern
839
+ async fn background_cleanup_task(repo: AsyncUserRepository) {
840
+ let mut interval = tokio::time::interval(Duration::from_secs(60));
841
+
842
+ loop {
843
+ interval.tick().await;
844
+
845
+ // Simulate cleanup logic
846
+ println!("Running background cleanup...");
847
+
848
+ // In a real application, you might clean up expired sessions,
849
+ // remove inactive users, etc.
850
+ tokio::time::sleep(Duration::from_millis(100)).await;
851
+ }
852
+ }
853
+
854
+ // Usage example
855
+ async fn async_patterns_example() -> Result<(), Box<dyn std::error::Error>> {
856
+ // Actor pattern
857
+ let user_actor = UserActorHandle::new();
858
+
859
+ let user = User::new(1, "Alice".to_string(), "alice@example.com".to_string());
860
+ user_actor.create_user(user).await?;
861
+
862
+ if let Some(retrieved_user) = user_actor.get_user(1).await {
863
+ println!("Retrieved user: {}", retrieved_user.display_info());
864
+ }
865
+
866
+ // Shared state pattern
867
+ let repo = AsyncUserRepository::new();
868
+
869
+ // Spawn background task
870
+ let repo_clone = repo.clone();
871
+ tokio::spawn(async move {
872
+ background_cleanup_task(repo_clone).await;
873
+ });
874
+
875
+ // Use repository
876
+ let user_id = repo.create_user("Bob".to_string(), "bob@example.com".to_string()).await;
877
+ println!("Created user with ID: {}", user_id);
878
+
879
+ if let Some(user) = repo.get_user(user_id).await {
880
+ println!("Found user: {}", user.display_info());
881
+ }
882
+
883
+ Ok(())
884
+ }
885
+ ```
886
+
887
+ ## Error Handling | 错误处理
888
+
889
+ ### 1. Custom Error Types | 自定义错误类型
890
+
891
+ ```rust
892
+ use std::fmt;
893
+
894
+ // ✅ Good: Custom error type with proper Display and Debug
895
+ #[derive(Debug)]
896
+ enum UserError {
897
+ NotFound(u64),
898
+ InvalidEmail(String),
899
+ DatabaseError(String),
900
+ ValidationError { field: String, message: String },
901
+ }
902
+
903
+ impl fmt::Display for UserError {
904
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
905
+ match self {
906
+ UserError::NotFound(id) => write!(f, "User with ID {} not found", id),
907
+ UserError::InvalidEmail(email) => write!(f, "Invalid email address: {}", email),
908
+ UserError::DatabaseError(msg) => write!(f, "Database error: {}", msg),
909
+ UserError::ValidationError { field, message } => {
910
+ write!(f, "Validation error on field '{}': {}", field, message)
911
+ }
912
+ }
913
+ }
914
+ }
915
+
916
+ impl std::error::Error for UserError {}
917
+
918
+ // ✅ Good: Result type alias for convenience
919
+ type UserResult<T> = Result<T, UserError>;
920
+
921
+ // ✅ Good: Using ? operator with custom errors
922
+ impl UserRepository {
923
+ fn validate_email(email: &str) -> UserResult<()> {
924
+ if email.is_empty() {
925
+ return Err(UserError::ValidationError {
926
+ field: "email".to_string(),
927
+ message: "cannot be empty".to_string(),
928
+ });
929
+ }
930
+
931
+ if !email.contains('@') {
932
+ return Err(UserError::InvalidEmail(email.to_string()));
933
+ }
934
+
935
+ Ok(())
936
+ }
937
+
938
+ fn create_user_safe(&mut self, name: String, email: String) -> UserResult<u64> {
939
+ // Validate input
940
+ if name.is_empty() {
941
+ return Err(UserError::ValidationError {
942
+ field: "name".to_string(),
943
+ message: "cannot be empty".to_string(),
944
+ });
945
+ }
946
+
947
+ Self::validate_email(&email)?; // Using ? operator
948
+
949
+ // Check for duplicates
950
+ for user in self.users.values() {
951
+ if user.email == email {
952
+ return Err(UserError::ValidationError {
953
+ field: "email".to_string(),
954
+ message: "already exists".to_string(),
955
+ });
956
+ }
957
+ }
958
+
959
+ // Create user
960
+ let id = self.next_id;
961
+ self.next_id += 1;
962
+
963
+ let user = User::new(id, name, email);
964
+ self.users.insert(id, user);
965
+
966
+ Ok(id)
967
+ }
968
+
969
+ fn get_user_safe(&self, id: u64) -> UserResult<&User> {
970
+ self.users.get(&id).ok_or(UserError::NotFound(id))
971
+ }
972
+ }
973
+ ```
974
+
975
+ ## Performance Patterns | 性能模式
976
+
977
+ ### 1. Zero-Cost Abstractions | 零成本抽象
978
+
979
+ ```rust
980
+ // ✅ Good: Iterator chains compile to efficient loops
981
+ fn process_numbers_efficiently(numbers: &[i32]) -> Vec<i32> {
982
+ numbers
983
+ .iter()
984
+ .filter(|&&x| x > 0)
985
+ .map(|&x| x * 2)
986
+ .collect()
987
+ }
988
+
989
+ // ✅ Good: Using iterators instead of indexing
990
+ fn sum_positive_numbers(numbers: &[i32]) -> i32 {
991
+ numbers.iter().filter(|&&x| x > 0).sum()
992
+ }
993
+
994
+ // ✅ Good: Avoiding allocations with iterator adaptors
995
+ fn find_first_large_number(numbers: &[i32]) -> Option<i32> {
996
+ numbers
997
+ .iter()
998
+ .filter(|&&x| x > 1000)
999
+ .copied()
1000
+ .next()
1001
+ }
1002
+
1003
+ // ✅ Good: Using Vec::with_capacity when size is known
1004
+ fn create_processed_data(input: &[i32]) -> Vec<String> {
1005
+ let mut result = Vec::with_capacity(input.len());
1006
+
1007
+ for &num in input {
1008
+ result.push(format!("Number: {}", num));
1009
+ }
1010
+
1011
+ result
1012
+ }
1013
+
1014
+ // ✅ Good: String building with capacity
1015
+ fn build_report(items: &[&str]) -> String {
1016
+ let total_len: usize = items.iter().map(|s| s.len()).sum();
1017
+ let mut report = String::with_capacity(total_len + items.len() * 10); // Extra space for formatting
1018
+
1019
+ for item in items {
1020
+ report.push_str("Item: ");
1021
+ report.push_str(item);
1022
+ report.push('\n');
1023
+ }
1024
+
1025
+ report
1026
+ }
1027
+ ```
1028
+
1029
+ ## Code Quality Checklist | 代码质量检查清单
1030
+
1031
+ - [ ] Ownership is clear and minimal cloning is used
1032
+ - [ ] Lifetimes are properly annotated where needed
1033
+ - [ ] Borrowing rules are followed without fighting the borrow checker
1034
+ - [ ] Error handling uses Result types and proper error propagation
1035
+ - [ ] Async code uses proper concurrency patterns
1036
+ - [ ] Smart pointers (Rc, Arc, Box) are used appropriately
1037
+ - [ ] Iterator chains are preferred over manual loops
1038
+ - [ ] Memory allocations are minimized with pre-allocation
1039
+ - [ ] Thread safety is ensured with proper synchronization primitives
1040
+ - [ ] Code compiles without warnings
1041
+ - [ ] Tests cover both success and error cases
1042
+ - [ ] Documentation includes examples and safety notes
1043
+
1044
+ ## 代码质量检查清单
1045
+
1046
+ - [ ] 所有权清晰,最少使用克隆
1047
+ - [ ] 在需要的地方正确注解生命周期
1048
+ - [ ] 遵循借用规则,不与借用检查器对抗
1049
+ - [ ] 错误处理使用 Result 类型和适当的错误传播
1050
+ - [ ] 异步代码使用适当的并发模式
1051
+ - [ ] 智能指针(Rc、Arc、Box)使用得当
1052
+ - [ ] 优先使用迭代器链而不是手动循环
1053
+ - [ ] 通过预分配最小化内存分配
1054
+ - [ ] 使用适当的同步原语确保线程安全
1055
+ - [ ] 代码编译无警告
1056
+ - [ ] 测试覆盖成功和错误情况
1057
+ - [ ] 文档包含示例和安全说明