moai-adk 0.4.5__py3-none-any.whl → 0.20.1__py3-none-any.whl

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.

Potentially problematic release.


This version of moai-adk might be problematic. Click here for more details.

Files changed (433) hide show
  1. moai_adk/__init__.py +1 -1
  2. moai_adk/__main__.py +74 -1
  3. moai_adk/cli/commands/__init__.py +1 -1
  4. moai_adk/cli/commands/analyze.py +119 -0
  5. moai_adk/cli/commands/backup.py +25 -1
  6. moai_adk/cli/commands/doctor.py +31 -5
  7. moai_adk/cli/commands/improve_user_experience.py +307 -0
  8. moai_adk/cli/commands/init.py +111 -10
  9. moai_adk/cli/commands/status.py +33 -3
  10. moai_adk/cli/commands/update.py +921 -130
  11. moai_adk/cli/commands/validate_links.py +120 -0
  12. moai_adk/cli/prompts/init_prompts.py +22 -87
  13. moai_adk/core/analysis/__init__.py +9 -0
  14. moai_adk/core/analysis/session_analyzer.py +388 -0
  15. moai_adk/core/analysis/tag_chain_analyzer.py +344 -0
  16. moai_adk/core/analysis/tag_chain_repair.py +879 -0
  17. moai_adk/core/config/__init__.py +19 -0
  18. moai_adk/core/config/migration.py +235 -0
  19. moai_adk/core/git/__init__.py +1 -1
  20. moai_adk/core/git/branch.py +1 -1
  21. moai_adk/core/git/commit.py +1 -1
  22. moai_adk/core/git/manager.py +1 -1
  23. moai_adk/core/issue_creator.py +313 -0
  24. moai_adk/core/mcp/setup.py +56 -0
  25. moai_adk/core/mcp/setup_old.py +296 -0
  26. moai_adk/core/project/backup_utils.py +1 -1
  27. moai_adk/core/project/checker.py +2 -2
  28. moai_adk/core/project/detector.py +211 -12
  29. moai_adk/core/project/initializer.py +85 -15
  30. moai_adk/core/project/phase_executor.py +76 -13
  31. moai_adk/core/project/validator.py +13 -13
  32. moai_adk/core/quality/__init__.py +1 -1
  33. moai_adk/core/quality/trust_checker.py +1 -1
  34. moai_adk/core/quality/validators/__init__.py +1 -1
  35. moai_adk/core/quality/validators/base_validator.py +1 -1
  36. moai_adk/core/tags/__init__.py +86 -0
  37. moai_adk/core/tags/auto_corrector.py +693 -0
  38. moai_adk/core/tags/ci_validator.py +463 -0
  39. moai_adk/core/tags/cli.py +283 -0
  40. moai_adk/core/tags/generator.py +109 -0
  41. moai_adk/core/tags/inserter.py +99 -0
  42. moai_adk/core/tags/mapper.py +126 -0
  43. moai_adk/core/tags/parser.py +76 -0
  44. moai_adk/core/tags/policy_validator.py +580 -0
  45. moai_adk/core/tags/pre_commit_validator.py +421 -0
  46. moai_adk/core/tags/reporter.py +956 -0
  47. moai_adk/core/tags/rollback_manager.py +525 -0
  48. moai_adk/core/tags/tags.py +149 -0
  49. moai_adk/core/tags/validator.py +897 -0
  50. moai_adk/core/template/__init__.py +1 -1
  51. moai_adk/core/template/backup.py +1 -1
  52. moai_adk/core/template/merger.py +50 -1
  53. moai_adk/core/template/processor.py +119 -13
  54. moai_adk/core/template_engine.py +268 -0
  55. moai_adk/templates/.claude/agents/alfred/backend-expert.md +348 -0
  56. moai_adk/templates/.claude/agents/alfred/cc-manager.md +209 -944
  57. moai_adk/templates/.claude/agents/alfred/database-expert.md +352 -0
  58. moai_adk/templates/.claude/agents/alfred/debug-helper.md +34 -5
  59. moai_adk/templates/.claude/agents/alfred/devops-expert.md +464 -0
  60. moai_adk/templates/.claude/agents/alfred/doc-syncer.md +38 -8
  61. moai_adk/templates/.claude/agents/alfred/format-expert.md +469 -0
  62. moai_adk/templates/.claude/agents/alfred/frontend-expert.md +357 -0
  63. moai_adk/templates/.claude/agents/alfred/git-manager.md +128 -9
  64. moai_adk/templates/.claude/agents/alfred/implementation-planner.md +104 -6
  65. moai_adk/templates/.claude/agents/alfred/project-manager.md +88 -16
  66. moai_adk/templates/.claude/agents/alfred/quality-gate.md +36 -9
  67. moai_adk/templates/.claude/agents/alfred/security-expert.md +270 -0
  68. moai_adk/templates/.claude/agents/alfred/skill-factory.md +865 -0
  69. moai_adk/templates/.claude/agents/alfred/spec-builder.md +214 -43
  70. moai_adk/templates/.claude/agents/alfred/tag-agent.md +111 -9
  71. moai_adk/templates/.claude/agents/alfred/tdd-implementer.md +309 -160
  72. moai_adk/templates/.claude/agents/alfred/trust-checker.md +36 -7
  73. moai_adk/templates/.claude/agents/alfred/ui-ux-expert.md +605 -0
  74. moai_adk/templates/.claude/commands/alfred/0-project.md +393 -966
  75. moai_adk/templates/.claude/commands/alfred/1-plan.md +651 -367
  76. moai_adk/templates/.claude/commands/alfred/2-run.md +388 -241
  77. moai_adk/templates/.claude/commands/alfred/3-sync.md +1921 -410
  78. moai_adk/templates/.claude/commands/alfred/9-feedback.md +153 -0
  79. moai_adk/templates/.claude/commands/alfred/release-new.md +3604 -0
  80. moai_adk/templates/.claude/hooks/alfred/core/project.py +484 -20
  81. moai_adk/templates/.claude/hooks/alfred/core/timeout.py +136 -0
  82. moai_adk/templates/.claude/hooks/alfred/core/ttl_cache.py +108 -0
  83. moai_adk/templates/.claude/hooks/alfred/core/version_cache.py +198 -0
  84. moai_adk/templates/.claude/hooks/alfred/handlers/__init__.py +14 -6
  85. moai_adk/templates/.claude/hooks/alfred/post_tool__enable_streaming_ui.py +50 -0
  86. moai_adk/templates/.claude/hooks/alfred/post_tool__log_changes.py +93 -0
  87. moai_adk/templates/.claude/hooks/alfred/post_tool__tag_auto_corrector.py +407 -0
  88. moai_adk/templates/.claude/hooks/alfred/pre_tool__auto_checkpoint.py +99 -0
  89. moai_adk/templates/.claude/hooks/alfred/pre_tool__realtime_tag_monitor.py +335 -0
  90. moai_adk/templates/.claude/hooks/alfred/pre_tool__tag_policy_validator.py +325 -0
  91. moai_adk/templates/.claude/hooks/alfred/session_end__cleanup.py +93 -0
  92. moai_adk/templates/.claude/hooks/alfred/session_start__auto_cleanup.py +580 -0
  93. moai_adk/templates/.claude/hooks/alfred/session_start__show_project_info.py +298 -0
  94. moai_adk/templates/.claude/hooks/alfred/shared/core/__init__.py +170 -0
  95. moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/checkpoint.py +3 -3
  96. moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/context.py +5 -5
  97. moai_adk/templates/.claude/hooks/alfred/shared/core/project.py +749 -0
  98. moai_adk/templates/.claude/hooks/alfred/shared/core/tags.py +230 -0
  99. moai_adk/templates/.claude/hooks/alfred/shared/core/version_cache.py +198 -0
  100. moai_adk/templates/.claude/hooks/alfred/shared/handlers/__init__.py +21 -0
  101. moai_adk/templates/.claude/hooks/alfred/shared/handlers/daily_analysis.py +351 -0
  102. moai_adk/templates/.claude/hooks/alfred/shared/handlers/notification.py +154 -0
  103. moai_adk/templates/.claude/hooks/alfred/shared/handlers/session.py +174 -0
  104. moai_adk/templates/.claude/hooks/alfred/shared/handlers/tool.py +87 -0
  105. moai_adk/templates/.claude/hooks/alfred/shared/handlers/user.py +61 -0
  106. moai_adk/templates/.claude/hooks/alfred/user_prompt__jit_load_docs.py +111 -0
  107. moai_adk/templates/.claude/hooks/alfred/utils/__init__.py +1 -0
  108. moai_adk/templates/.claude/hooks/alfred/utils/hook_config.py +94 -0
  109. moai_adk/templates/.claude/hooks/alfred/utils/timeout.py +161 -0
  110. moai_adk/templates/.claude/output-styles/alfred/alfred-moai-adk-beginner.md +267 -0
  111. moai_adk/templates/.claude/output-styles/alfred/keating-personal-tutor.md +440 -0
  112. moai_adk/templates/.claude/output-styles/alfred/r2d2-agentic-coding.md +583 -0
  113. moai_adk/templates/.claude/settings.json +96 -14
  114. moai_adk/templates/.claude/skills/moai-alfred-agent-guide/SKILL.md +70 -0
  115. moai_adk/templates/.claude/skills/moai-alfred-agent-guide/examples.md +62 -0
  116. moai_adk/templates/.claude/skills/moai-alfred-agent-guide/reference.md +242 -0
  117. moai_adk/templates/.claude/skills/moai-alfred-ask-user-questions/SKILL.md +237 -0
  118. moai_adk/templates/.claude/skills/moai-alfred-ask-user-questions/examples.md +871 -0
  119. moai_adk/templates/.claude/skills/moai-alfred-ask-user-questions/reference.md +653 -0
  120. moai_adk/templates/.claude/skills/moai-alfred-clone-pattern/README.md +162 -0
  121. moai_adk/templates/.claude/skills/moai-alfred-clone-pattern/SKILL.md +227 -0
  122. moai_adk/templates/.claude/skills/moai-alfred-clone-pattern/examples.md +354 -0
  123. moai_adk/templates/.claude/skills/moai-alfred-clone-pattern/reference.md +158 -0
  124. moai_adk/templates/.claude/skills/moai-alfred-code-reviewer/SKILL.md +179 -79
  125. moai_adk/templates/.claude/skills/moai-alfred-code-reviewer/examples.md +117 -0
  126. moai_adk/templates/.claude/skills/moai-alfred-code-reviewer/scripts/pre-review-check.sh +62 -0
  127. moai_adk/templates/.claude/skills/moai-alfred-config-schema/SKILL.md +132 -0
  128. moai_adk/templates/.claude/skills/moai-alfred-config-schema/examples.md +28 -0
  129. moai_adk/templates/.claude/skills/moai-alfred-config-schema/reference.md +444 -0
  130. moai_adk/templates/.claude/skills/moai-alfred-context-budget/SKILL.md +62 -0
  131. moai_adk/templates/.claude/skills/moai-alfred-context-budget/examples.md +28 -0
  132. moai_adk/templates/.claude/skills/moai-alfred-context-budget/reference.md +405 -0
  133. moai_adk/templates/.claude/skills/moai-alfred-dev-guide/SKILL.md +51 -0
  134. moai_adk/templates/.claude/skills/moai-alfred-dev-guide/examples.md +355 -0
  135. moai_adk/templates/.claude/skills/moai-alfred-dev-guide/reference.md +239 -0
  136. moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/SKILL.md +323 -0
  137. moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/examples.md +286 -0
  138. moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/reference.md +126 -0
  139. moai_adk/templates/.claude/skills/moai-alfred-issue-labels/SKILL.md +229 -0
  140. moai_adk/templates/.claude/skills/moai-alfred-issue-labels/examples.md +4 -0
  141. moai_adk/templates/.claude/skills/moai-alfred-issue-labels/reference.md +150 -0
  142. moai_adk/templates/.claude/skills/moai-alfred-language-detection/SKILL.md +87 -73
  143. moai_adk/templates/.claude/skills/moai-alfred-language-detection/examples.md +29 -0
  144. moai_adk/templates/.claude/skills/moai-alfred-language-detection/reference.md +28 -0
  145. moai_adk/templates/.claude/skills/moai-alfred-personas/README.md +42 -0
  146. moai_adk/templates/.claude/skills/moai-alfred-personas/SKILL.md +429 -0
  147. moai_adk/templates/.claude/skills/moai-alfred-personas/examples.md +520 -0
  148. moai_adk/templates/.claude/skills/moai-alfred-personas/reference.md +405 -0
  149. moai_adk/templates/.claude/skills/moai-alfred-practices/SKILL.md +89 -0
  150. moai_adk/templates/.claude/skills/moai-alfred-practices/examples.md +122 -0
  151. moai_adk/templates/.claude/skills/moai-alfred-practices/reference.md +369 -0
  152. moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/SKILL.md +508 -0
  153. moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/examples.md +481 -0
  154. moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/reference.md +100 -0
  155. moai_adk/templates/.claude/skills/moai-alfred-rules/SKILL.md +77 -0
  156. moai_adk/templates/.claude/skills/moai-alfred-rules/examples.md +265 -0
  157. moai_adk/templates/.claude/skills/moai-alfred-rules/reference.md +539 -0
  158. moai_adk/templates/.claude/skills/moai-alfred-session-state/SKILL.md +320 -0
  159. moai_adk/templates/.claude/skills/moai-alfred-session-state/examples.md +4 -0
  160. moai_adk/templates/.claude/skills/moai-alfred-session-state/reference.md +84 -0
  161. moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/README.md +137 -0
  162. moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/SKILL.md +219 -0
  163. moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/examples/validate-spec.sh +161 -0
  164. moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/examples.md +541 -0
  165. moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/reference.md +622 -0
  166. moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/SKILL.md +19 -0
  167. moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/examples.md +4 -0
  168. moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/reference.md +211 -0
  169. moai_adk/templates/.claude/skills/moai-alfred-workflow/SKILL.md +288 -0
  170. moai_adk/templates/.claude/skills/moai-cc-agents/SKILL.md +269 -0
  171. moai_adk/templates/.claude/skills/moai-cc-agents/templates/agent-template.md +32 -0
  172. moai_adk/templates/.claude/skills/moai-cc-claude-md/SKILL.md +298 -0
  173. moai_adk/templates/.claude/skills/moai-cc-claude-md/templates/CLAUDE-template.md +26 -0
  174. moai_adk/templates/.claude/skills/moai-cc-commands/SKILL.md +307 -0
  175. moai_adk/templates/.claude/skills/moai-cc-commands/templates/command-template.md +21 -0
  176. moai_adk/templates/.claude/skills/moai-cc-hooks/SKILL.md +252 -0
  177. moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/pre-bash-check.sh +19 -0
  178. moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/preserve-permissions.sh +19 -0
  179. moai_adk/templates/.claude/skills/moai-cc-hooks/scripts/validate-bash-command.py +24 -0
  180. moai_adk/templates/.claude/skills/moai-cc-mcp-plugins/SKILL.md +199 -0
  181. moai_adk/templates/.claude/skills/moai-cc-mcp-plugins/templates/settings-mcp-template.json +39 -0
  182. moai_adk/templates/.claude/skills/moai-cc-memory/SKILL.md +316 -0
  183. moai_adk/templates/.claude/skills/moai-cc-memory/templates/session-summary-template.md +18 -0
  184. moai_adk/templates/.claude/skills/moai-cc-settings/SKILL.md +263 -0
  185. moai_adk/templates/.claude/skills/moai-cc-settings/templates/settings-complete-template.json +30 -0
  186. moai_adk/templates/.claude/skills/moai-cc-skill-factory/CHECKLIST.md +482 -0
  187. moai_adk/templates/.claude/skills/moai-cc-skill-factory/EXAMPLES.md +303 -0
  188. moai_adk/templates/.claude/skills/moai-cc-skill-factory/INTERACTIVE-DISCOVERY.md +524 -0
  189. moai_adk/templates/.claude/skills/moai-cc-skill-factory/METADATA.md +477 -0
  190. moai_adk/templates/.claude/skills/moai-cc-skill-factory/PARALLEL-ANALYSIS-REPORT.md +429 -0
  191. moai_adk/templates/.claude/skills/moai-cc-skill-factory/PYTHON-VERSION-MATRIX.md +391 -0
  192. moai_adk/templates/.claude/skills/moai-cc-skill-factory/SKILL-FACTORY-WORKFLOW.md +431 -0
  193. moai_adk/templates/.claude/skills/moai-cc-skill-factory/SKILL-UPDATE-ADVISOR.md +577 -0
  194. moai_adk/templates/.claude/skills/moai-cc-skill-factory/SKILL.md +273 -0
  195. moai_adk/templates/.claude/skills/moai-cc-skill-factory/STEP-BY-STEP-GUIDE.md +466 -0
  196. moai_adk/templates/.claude/skills/moai-cc-skill-factory/STRUCTURE.md +583 -0
  197. moai_adk/templates/.claude/skills/moai-cc-skill-factory/WEB-RESEARCH.md +526 -0
  198. moai_adk/templates/.claude/skills/moai-cc-skill-factory/reference.md +608 -0
  199. moai_adk/templates/.claude/skills/moai-cc-skill-factory/scripts/generate-structure.sh +328 -0
  200. moai_adk/templates/.claude/skills/moai-cc-skill-factory/scripts/validate-skill.sh +312 -0
  201. moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/SKILL_TEMPLATE.md +245 -0
  202. moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/examples-template.md +285 -0
  203. moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/reference-template.md +278 -0
  204. moai_adk/templates/.claude/skills/moai-cc-skill-factory/templates/scripts-template.sh +303 -0
  205. moai_adk/templates/.claude/skills/moai-cc-skills/SKILL.md +291 -0
  206. moai_adk/templates/.claude/skills/moai-cc-skills/templates/SKILL-template.md +15 -0
  207. moai_adk/templates/.claude/skills/moai-change-logger/SKILL.md +563 -0
  208. moai_adk/templates/.claude/skills/moai-design-systems/SKILL.md +802 -0
  209. moai_adk/templates/.claude/skills/moai-design-systems/examples.md +1238 -0
  210. moai_adk/templates/.claude/skills/moai-design-systems/reference.md +673 -0
  211. moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +234 -43
  212. moai_adk/templates/.claude/skills/moai-domain-backend/examples.md +1633 -0
  213. moai_adk/templates/.claude/skills/moai-domain-backend/reference.md +660 -0
  214. moai_adk/templates/.claude/skills/moai-domain-cli-tool/SKILL.md +97 -69
  215. moai_adk/templates/.claude/skills/moai-domain-cli-tool/examples.md +29 -0
  216. moai_adk/templates/.claude/skills/moai-domain-cli-tool/reference.md +30 -0
  217. moai_adk/templates/.claude/skills/moai-domain-data-science/SKILL.md +97 -72
  218. moai_adk/templates/.claude/skills/moai-domain-data-science/examples.md +29 -0
  219. moai_adk/templates/.claude/skills/moai-domain-data-science/reference.md +30 -0
  220. moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +97 -74
  221. moai_adk/templates/.claude/skills/moai-domain-database/examples.md +29 -0
  222. moai_adk/templates/.claude/skills/moai-domain-database/reference.md +30 -0
  223. moai_adk/templates/.claude/skills/moai-domain-devops/SKILL.md +98 -74
  224. moai_adk/templates/.claude/skills/moai-domain-devops/examples.md +29 -0
  225. moai_adk/templates/.claude/skills/moai-domain-devops/reference.md +31 -0
  226. moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +102 -73
  227. moai_adk/templates/.claude/skills/moai-domain-frontend/examples.md +29 -0
  228. moai_adk/templates/.claude/skills/moai-domain-frontend/reference.md +31 -0
  229. moai_adk/templates/.claude/skills/moai-domain-ml/SKILL.md +97 -73
  230. moai_adk/templates/.claude/skills/moai-domain-ml/examples.md +29 -0
  231. moai_adk/templates/.claude/skills/moai-domain-ml/reference.md +30 -0
  232. moai_adk/templates/.claude/skills/moai-domain-mobile-app/SKILL.md +97 -67
  233. moai_adk/templates/.claude/skills/moai-domain-mobile-app/examples.md +29 -0
  234. moai_adk/templates/.claude/skills/moai-domain-mobile-app/reference.md +30 -0
  235. moai_adk/templates/.claude/skills/moai-domain-security/SKILL.md +97 -79
  236. moai_adk/templates/.claude/skills/moai-domain-security/examples.md +29 -0
  237. moai_adk/templates/.claude/skills/moai-domain-security/reference.md +30 -0
  238. moai_adk/templates/.claude/skills/moai-domain-web-api/SKILL.md +97 -71
  239. moai_adk/templates/.claude/skills/moai-domain-web-api/examples.md +29 -0
  240. moai_adk/templates/.claude/skills/moai-domain-web-api/reference.md +30 -0
  241. moai_adk/templates/.claude/skills/moai-essentials-debug/SKILL.md +265 -64
  242. moai_adk/templates/.claude/skills/moai-essentials-debug/examples.md +1064 -0
  243. moai_adk/templates/.claude/skills/moai-essentials-debug/reference.md +1047 -0
  244. moai_adk/templates/.claude/skills/moai-essentials-perf/SKILL.md +87 -78
  245. moai_adk/templates/.claude/skills/moai-essentials-perf/examples.md +29 -0
  246. moai_adk/templates/.claude/skills/moai-essentials-perf/reference.md +28 -0
  247. moai_adk/templates/.claude/skills/moai-essentials-refactor/SKILL.md +87 -70
  248. moai_adk/templates/.claude/skills/moai-essentials-refactor/examples.md +29 -0
  249. moai_adk/templates/.claude/skills/moai-essentials-refactor/reference.md +28 -0
  250. moai_adk/templates/.claude/skills/moai-essentials-review/SKILL.md +87 -86
  251. moai_adk/templates/.claude/skills/moai-essentials-review/examples.md +29 -0
  252. moai_adk/templates/.claude/skills/moai-essentials-review/reference.md +28 -0
  253. moai_adk/templates/.claude/skills/moai-foundation-ears/SKILL.md +80 -62
  254. moai_adk/templates/.claude/skills/moai-foundation-ears/examples.md +29 -0
  255. moai_adk/templates/.claude/skills/moai-foundation-ears/reference.md +28 -0
  256. moai_adk/templates/.claude/skills/moai-foundation-git/SKILL.md +207 -50
  257. moai_adk/templates/.claude/skills/moai-foundation-git/examples.md +29 -0
  258. moai_adk/templates/.claude/skills/moai-foundation-git/reference.md +29 -0
  259. moai_adk/templates/.claude/skills/moai-foundation-langs/SKILL.md +90 -71
  260. moai_adk/templates/.claude/skills/moai-foundation-langs/examples.md +29 -0
  261. moai_adk/templates/.claude/skills/moai-foundation-langs/reference.md +28 -0
  262. moai_adk/templates/.claude/skills/moai-foundation-specs/SKILL.md +78 -58
  263. moai_adk/templates/.claude/skills/moai-foundation-specs/examples.md +29 -0
  264. moai_adk/templates/.claude/skills/moai-foundation-specs/reference.md +28 -0
  265. moai_adk/templates/.claude/skills/moai-foundation-tags/SKILL.md +78 -51
  266. moai_adk/templates/.claude/skills/moai-foundation-tags/examples.md +29 -0
  267. moai_adk/templates/.claude/skills/moai-foundation-tags/reference.md +28 -0
  268. moai_adk/templates/.claude/skills/moai-foundation-trust/.!11330!examples.md +0 -0
  269. moai_adk/templates/.claude/skills/moai-foundation-trust/SKILL.md +253 -32
  270. moai_adk/templates/.claude/skills/moai-foundation-trust/examples.md +0 -0
  271. moai_adk/templates/.claude/skills/moai-foundation-trust/reference.md +1099 -0
  272. moai_adk/templates/.claude/skills/moai-jit-docs-enhanced/SKILL.md +460 -0
  273. moai_adk/templates/.claude/skills/moai-lang-c/SKILL.md +98 -74
  274. moai_adk/templates/.claude/skills/moai-lang-c/examples.md +29 -0
  275. moai_adk/templates/.claude/skills/moai-lang-c/reference.md +31 -0
  276. moai_adk/templates/.claude/skills/moai-lang-cpp/SKILL.md +98 -76
  277. moai_adk/templates/.claude/skills/moai-lang-cpp/examples.md +29 -0
  278. moai_adk/templates/.claude/skills/moai-lang-cpp/reference.md +31 -0
  279. moai_adk/templates/.claude/skills/moai-lang-csharp/SKILL.md +2358 -70
  280. moai_adk/templates/.claude/skills/moai-lang-csharp/examples.md +29 -0
  281. moai_adk/templates/.claude/skills/moai-lang-csharp/reference.md +30 -0
  282. moai_adk/templates/.claude/skills/moai-lang-dart/SKILL.md +2962 -68
  283. moai_adk/templates/.claude/skills/moai-lang-dart/examples.md +29 -0
  284. moai_adk/templates/.claude/skills/moai-lang-dart/reference.md +30 -0
  285. moai_adk/templates/.claude/skills/moai-lang-go/SKILL.md +1898 -70
  286. moai_adk/templates/.claude/skills/moai-lang-go/examples.md +29 -0
  287. moai_adk/templates/.claude/skills/moai-lang-go/reference.md +31 -0
  288. moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +1465 -68
  289. moai_adk/templates/.claude/skills/moai-lang-java/examples.md +29 -0
  290. moai_adk/templates/.claude/skills/moai-lang-java/reference.md +31 -0
  291. moai_adk/templates/.claude/skills/moai-lang-javascript/SKILL.md +2364 -66
  292. moai_adk/templates/.claude/skills/moai-lang-javascript/examples.md +29 -0
  293. moai_adk/templates/.claude/skills/moai-lang-javascript/reference.md +32 -0
  294. moai_adk/templates/.claude/skills/moai-lang-kotlin/SKILL.md +1630 -69
  295. moai_adk/templates/.claude/skills/moai-lang-kotlin/examples.md +29 -0
  296. moai_adk/templates/.claude/skills/moai-lang-kotlin/reference.md +31 -0
  297. moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +89 -61
  298. moai_adk/templates/.claude/skills/moai-lang-php/examples.md +29 -0
  299. moai_adk/templates/.claude/skills/moai-lang-php/reference.md +30 -0
  300. moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +735 -66
  301. moai_adk/templates/.claude/skills/moai-lang-python/examples.md +624 -0
  302. moai_adk/templates/.claude/skills/moai-lang-python/reference.md +316 -0
  303. moai_adk/templates/.claude/skills/moai-lang-r/SKILL.md +97 -73
  304. moai_adk/templates/.claude/skills/moai-lang-r/examples.md +29 -0
  305. moai_adk/templates/.claude/skills/moai-lang-r/reference.md +30 -0
  306. moai_adk/templates/.claude/skills/moai-lang-ruby/SKILL.md +98 -73
  307. moai_adk/templates/.claude/skills/moai-lang-ruby/examples.md +29 -0
  308. moai_adk/templates/.claude/skills/moai-lang-ruby/reference.md +31 -0
  309. moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +1834 -70
  310. moai_adk/templates/.claude/skills/moai-lang-rust/examples.md +29 -0
  311. moai_adk/templates/.claude/skills/moai-lang-rust/reference.md +31 -0
  312. moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +99 -74
  313. moai_adk/templates/.claude/skills/moai-lang-scala/examples.md +29 -0
  314. moai_adk/templates/.claude/skills/moai-lang-scala/reference.md +30 -0
  315. moai_adk/templates/.claude/skills/moai-lang-shell/SKILL.md +97 -74
  316. moai_adk/templates/.claude/skills/moai-lang-shell/examples.md +29 -0
  317. moai_adk/templates/.claude/skills/moai-lang-shell/reference.md +30 -0
  318. moai_adk/templates/.claude/skills/moai-lang-sql/SKILL.md +98 -74
  319. moai_adk/templates/.claude/skills/moai-lang-sql/examples.md +29 -0
  320. moai_adk/templates/.claude/skills/moai-lang-sql/reference.md +31 -0
  321. moai_adk/templates/.claude/skills/moai-lang-swift/SKILL.md +1959 -69
  322. moai_adk/templates/.claude/skills/moai-lang-swift/examples.md +29 -0
  323. moai_adk/templates/.claude/skills/moai-lang-swift/reference.md +30 -0
  324. moai_adk/templates/.claude/skills/moai-lang-template/SKILL.md +348 -0
  325. moai_adk/templates/.claude/skills/moai-lang-template/VARIABLES.md +98 -0
  326. moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +1230 -66
  327. moai_adk/templates/.claude/skills/moai-lang-typescript/examples.md +29 -0
  328. moai_adk/templates/.claude/skills/moai-lang-typescript/reference.md +34 -0
  329. moai_adk/templates/.claude/skills/moai-learning-optimizer/SKILL.md +575 -0
  330. moai_adk/templates/.claude/skills/moai-project-batch-questions/README.md +50 -0
  331. moai_adk/templates/.claude/skills/moai-project-batch-questions/SKILL.md +304 -0
  332. moai_adk/templates/.claude/skills/moai-project-batch-questions/examples.md +417 -0
  333. moai_adk/templates/.claude/skills/moai-project-batch-questions/reference.md +704 -0
  334. moai_adk/templates/.claude/skills/moai-project-config-manager/README.md +87 -0
  335. moai_adk/templates/.claude/skills/moai-project-config-manager/SKILL.md +552 -0
  336. moai_adk/templates/.claude/skills/moai-project-config-manager/examples.md +1109 -0
  337. moai_adk/templates/.claude/skills/moai-project-config-manager/reference.md +514 -0
  338. moai_adk/templates/.claude/skills/moai-project-config-manager/validate.py +106 -0
  339. moai_adk/templates/.claude/skills/moai-project-documentation/README.md +11 -0
  340. moai_adk/templates/.claude/skills/moai-project-documentation/SKILL.md +622 -0
  341. moai_adk/templates/.claude/skills/moai-project-documentation/examples.md +20 -0
  342. moai_adk/templates/.claude/skills/moai-project-documentation/reference.md +12 -0
  343. moai_adk/templates/.claude/skills/moai-project-language-initializer/README.md +152 -0
  344. moai_adk/templates/.claude/skills/moai-project-language-initializer/SKILL.md +285 -0
  345. moai_adk/templates/.claude/skills/moai-project-language-initializer/examples.md +333 -0
  346. moai_adk/templates/.claude/skills/moai-project-language-initializer/reference.md +386 -0
  347. moai_adk/templates/.claude/skills/moai-project-template-optimizer/README.md +49 -0
  348. moai_adk/templates/.claude/skills/moai-project-template-optimizer/SKILL.md +319 -0
  349. moai_adk/templates/.claude/skills/moai-project-template-optimizer/examples.md +58 -0
  350. moai_adk/templates/.claude/skills/moai-project-template-optimizer/reference.md +123 -0
  351. moai_adk/templates/.claude/skills/moai-session-info/SKILL.md +314 -0
  352. moai_adk/templates/.claude/skills/moai-streaming-ui/SKILL.md +552 -0
  353. moai_adk/templates/.claude/skills/moai-tag-policy-validator/SKILL.md +570 -0
  354. moai_adk/templates/.git-hooks/pre-commit +66 -0
  355. moai_adk/templates/.git-hooks/pre-push +255 -0
  356. moai_adk/templates/.github/workflows/c-tag-validation.yml +11 -0
  357. moai_adk/templates/.github/workflows/cpp-tag-validation.yml +11 -0
  358. moai_adk/templates/.github/workflows/csharp-tag-validation.yml +11 -0
  359. moai_adk/templates/.github/workflows/dart-tag-validation.yml +11 -0
  360. moai_adk/templates/.github/workflows/go-tag-validation.yml +130 -0
  361. moai_adk/templates/.github/workflows/java-tag-validation.yml +11 -0
  362. moai_adk/templates/.github/workflows/javascript-tag-validation.yml +135 -0
  363. moai_adk/templates/.github/workflows/kotlin-tag-validation.yml +11 -0
  364. moai_adk/templates/.github/workflows/moai-gitflow.yml +166 -3
  365. moai_adk/templates/.github/workflows/moai-release-create.yml +100 -0
  366. moai_adk/templates/.github/workflows/moai-release-pipeline.yml +188 -0
  367. moai_adk/templates/.github/workflows/php-tag-validation.yml +11 -0
  368. moai_adk/templates/.github/workflows/python-tag-validation.yml +118 -0
  369. moai_adk/templates/.github/workflows/release.yml +118 -0
  370. moai_adk/templates/.github/workflows/ruby-tag-validation.yml +11 -0
  371. moai_adk/templates/.github/workflows/rust-tag-validation.yml +11 -0
  372. moai_adk/templates/.github/workflows/shell-tag-validation.yml +11 -0
  373. moai_adk/templates/.github/workflows/spec-issue-sync.yml +338 -0
  374. moai_adk/templates/.github/workflows/swift-tag-validation.yml +11 -0
  375. moai_adk/templates/.github/workflows/tag-report.yml +269 -0
  376. moai_adk/templates/.github/workflows/tag-validation.yml +186 -0
  377. moai_adk/templates/.github/workflows/typescript-tag-validation.yml +154 -0
  378. moai_adk/templates/.mcp.json +31 -0
  379. moai_adk/templates/.moai/config.json +80 -7
  380. moai_adk/templates/CLAUDE.md +562 -546
  381. moai_adk/utils/banner.py +5 -5
  382. moai_adk/utils/common.py +294 -0
  383. moai_adk/utils/link_validator.py +235 -0
  384. moai_adk/utils/logger.py +8 -8
  385. moai_adk/utils/user_experience.py +451 -0
  386. moai_adk-0.20.1.dist-info/METADATA +233 -0
  387. moai_adk-0.20.1.dist-info/RECORD +404 -0
  388. moai_adk/templates/.claude/hooks/alfred/README.md +0 -230
  389. moai_adk/templates/.claude/hooks/alfred/alfred_hooks.py +0 -156
  390. moai_adk/templates/.claude/hooks/alfred/core/__init__.py +0 -85
  391. moai_adk/templates/.claude/hooks/alfred/handlers/notification.py +0 -25
  392. moai_adk/templates/.claude/hooks/alfred/handlers/session.py +0 -92
  393. moai_adk/templates/.claude/hooks/alfred/handlers/tool.py +0 -70
  394. moai_adk/templates/.claude/hooks/alfred/handlers/user.py +0 -41
  395. moai_adk/templates/.claude/output-styles/alfred/agentic-coding.md +0 -636
  396. moai_adk/templates/.claude/output-styles/alfred/moai-adk-learning.md +0 -692
  397. moai_adk/templates/.claude/output-styles/alfred/study-with-alfred.md +0 -470
  398. moai_adk/templates/.claude/skills/moai-alfred-debugger-pro/SKILL.md +0 -103
  399. moai_adk/templates/.claude/skills/moai-alfred-ears-authoring/SKILL.md +0 -103
  400. moai_adk/templates/.claude/skills/moai-alfred-git-workflow/SKILL.md +0 -95
  401. moai_adk/templates/.claude/skills/moai-alfred-performance-optimizer/SKILL.md +0 -105
  402. moai_adk/templates/.claude/skills/moai-alfred-refactoring-coach/SKILL.md +0 -97
  403. moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-validation/SKILL.md +0 -97
  404. moai_adk/templates/.claude/skills/moai-alfred-tag-scanning/SKILL.md +0 -90
  405. moai_adk/templates/.claude/skills/moai-alfred-trust-validation/SKILL.md +0 -99
  406. moai_adk/templates/.claude/skills/moai-alfred-tui-survey/SKILL.md +0 -87
  407. moai_adk/templates/.claude/skills/moai-alfred-tui-survey/examples.md +0 -62
  408. moai_adk/templates/.claude/skills/moai-claude-code/SKILL.md +0 -94
  409. moai_adk/templates/.claude/skills/moai-claude-code/examples.md +0 -513
  410. moai_adk/templates/.claude/skills/moai-claude-code/reference.md +0 -433
  411. moai_adk/templates/.claude/skills/moai-claude-code/templates/agent-full.md +0 -332
  412. moai_adk/templates/.claude/skills/moai-claude-code/templates/command-full.md +0 -384
  413. moai_adk/templates/.claude/skills/moai-claude-code/templates/plugin-full.json +0 -363
  414. moai_adk/templates/.claude/skills/moai-claude-code/templates/settings-full.json +0 -595
  415. moai_adk/templates/.claude/skills/moai-claude-code/templates/skill-full.md +0 -496
  416. moai_adk/templates/.claude/skills/moai-lang-clojure/SKILL.md +0 -100
  417. moai_adk/templates/.claude/skills/moai-lang-elixir/SKILL.md +0 -99
  418. moai_adk/templates/.claude/skills/moai-lang-haskell/SKILL.md +0 -100
  419. moai_adk/templates/.claude/skills/moai-lang-julia/SKILL.md +0 -98
  420. moai_adk/templates/.claude/skills/moai-lang-lua/SKILL.md +0 -98
  421. moai_adk/templates/.github/PULL_REQUEST_TEMPLATE.md +0 -69
  422. moai_adk/templates/.moai/memory/development-guide.md +0 -344
  423. moai_adk/templates/.moai/memory/gitflow-protection-policy.md +0 -220
  424. moai_adk/templates/.moai/memory/spec-metadata.md +0 -356
  425. moai_adk/templates/.moai/project/product.md +0 -161
  426. moai_adk/templates/.moai/project/structure.md +0 -156
  427. moai_adk/templates/.moai/project/tech.md +0 -227
  428. moai_adk/templates/__init__.py +0 -2
  429. moai_adk-0.4.5.dist-info/METADATA +0 -369
  430. moai_adk-0.4.5.dist-info/RECORD +0 -152
  431. {moai_adk-0.4.5.dist-info → moai_adk-0.20.1.dist-info}/WHEEL +0 -0
  432. {moai_adk-0.4.5.dist-info → moai_adk-0.20.1.dist-info}/entry_points.txt +0 -0
  433. {moai_adk-0.4.5.dist-info → moai_adk-0.20.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,100 +1,1864 @@
1
1
  ---
2
-
3
2
  name: moai-lang-rust
4
- description: Rust best practices with cargo test, clippy, rustfmt, and ownership/borrow checker mastery. Use when writing or reviewing Rust code in project workflows.
3
+ version: 2.0.0
4
+ created: 2025-11-06
5
+ updated: 2025-11-06
6
+ status: active
7
+ description: "Rust best practices with systems programming, performance-critical applications, and memory-safe patterns for 2025"
8
+ keywords: [rust, systems, performance, memory-safety, concurrency, web-services, embedded, blockchain]
5
9
  allowed-tools:
6
10
  - Read
11
+ - Write
12
+ - Edit
7
13
  - Bash
14
+ - WebFetch
15
+ - WebSearch
8
16
  ---
9
17
 
10
- # Rust Expert
18
+ # Rust Development Mastery
19
+
20
+ **Modern Rust Development with 2025 Best Practices**
21
+
22
+ > Comprehensive Rust development guidance covering systems programming, high-performance applications, web services, embedded development, and production-safe code using the latest tools and methodologies.
23
+
24
+ ## What It Does
25
+
26
+ - **Systems Programming**: OS-level utilities, embedded systems, low-level optimizations
27
+ - **High-Performance Web Services**: Actix-web, Axum, and async frameworks
28
+ - **Memory-Safe Concurrency**: Fearless concurrency with ownership and borrowing
29
+ - **CLI Applications**: Fast, safe command-line tools and utilities
30
+ - **Blockchain & Crypto**: Smart contracts, DeFi protocols, cryptographic applications
31
+ - **Game Development**: Game engines, real-time systems, graphics programming
32
+ - **DevOps & Infrastructure**: Monitoring tools, containerized applications, cloud services
11
33
 
12
- ## Skill Metadata
13
- | Field | Value |
14
- | ----- | ----- |
15
- | Allowed tools | Read (read_file), Bash (terminal) |
16
- | Auto-load | On demand when language keywords are detected |
17
- | Trigger cues | Rust code discussions, framework guidance, or file extensions such as .rs. |
18
- | Tier | 3 |
34
+ ## When to Use
19
35
 
20
- ## What it does
36
+ ### Perfect Scenarios
37
+ - **Performance-critical applications requiring zero-cost abstractions**
38
+ - **Systems programming and embedded development**
39
+ - **Web services requiring maximum throughput and security**
40
+ - **CLI tools and developer utilities**
41
+ - **Blockchain and cryptocurrency applications**
42
+ - **Game engines and real-time systems**
43
+ - **Applications requiring memory safety without garbage collection**
21
44
 
22
- Provides Rust-specific expertise for TDD development, including cargo test, clippy linting, rustfmt formatting, and ownership/borrow checker compliance.
45
+ ### Common Triggers
46
+ - "Create Rust web service"
47
+ - "Build Rust CLI tool"
48
+ - "Rust performance optimization"
49
+ - "Rust memory safety"
50
+ - "Systems programming with Rust"
51
+ - "Async Rust patterns"
23
52
 
24
- ## When to use
53
+ ## Tool Version Matrix (2025-11-06)
25
54
 
26
- - Engages when the conversation references Rust work, frameworks, or files like .rs.
27
- - “Writing Rust tests”, “How to use cargo tests”, “Ownership rules”
28
- - Automatically invoked when working with Rust projects
29
- - Rust SPEC implementation (`/alfred:2-run`)
55
+ ### Core Rust
56
+ - **Rust**: 1.91.x (latest) / 1.89.x (LTS)
57
+ - **Cargo**: Built-in package manager and build tool
58
+ - **Rustup**: Rust version manager
59
+ - **Rust-analyzer**: Advanced LSP support
30
60
 
31
- ## How it works
61
+ ### Web Frameworks
62
+ - **Actix-web**: 4.9.x - High-performance web framework
63
+ - **Axum**: 0.8.x - Web framework from tokio team
64
+ - **Rocket**: 0.6.x - Web framework with macros
65
+ - **Poem**: 3.1.x - Modular web framework
66
+ - **Warp**: 0.4.x - Composable web server
32
67
 
33
- **TDD Framework**:
34
- - **cargo test**: Built-in test framework
35
- - **proptest**: Property-based testing
36
- - **criterion**: Benchmarking
37
- - Test coverage with `cargo tarpaulin` or `cargo llvm-cov`
68
+ ### Async Runtime
69
+ - **Tokio**: 1.42.x - Asynchronous runtime
70
+ - **Async-std**: 1.13.x - Async standard library
71
+ - **Smol**: 2.0.x - Compact async runtime
38
72
 
39
- **Code Quality**:
40
- - **clippy**: Rust linter with 500+ lint rules
41
- - **rustfmt**: Automatic code formatting
42
- - **cargo check**: Fast compilation check
43
- - **cargo audit**: Security vulnerability scanning
73
+ ### Database & Storage
74
+ - **SQLx**: 0.8.x - Async SQL toolkit
75
+ - **Diesel**: 2.2.x - ORM and query builder
76
+ - **Serde**: 1.0.x - Serialization framework
77
+ - **Redis**: 0.26.x - Redis client
44
78
 
45
- **Memory Safety**:
46
- - **Ownership**: One owner per value
47
- - **Borrowing**: Immutable (&T) or mutable (&mut T) references
48
- - **Lifetimes**: Explicit lifetime annotations when needed
49
- - **Move semantics**: Understanding Copy vs Clone
79
+ ### Testing Tools
80
+ - **Tokio-test**: 0.4.x - Async testing utilities
81
+ - **Mockall**: 0.13.x - Mocking framework
82
+ - **Cucumber-rs**: 0.22.x - BDD testing
83
+ - **Proptest**: 1.5.x - Property-based testing
50
84
 
51
- **Rust Patterns**:
52
- - Result<T, E> for error handling (no exceptions)
53
- - Option<T> for nullable values
54
- - Traits for polymorphism
55
- - Match expressions for exhaustive handling
85
+ ### Development Tools
86
+ - **Clippy**: Built-in linter
87
+ - **rustfmt**: Built-in formatter
88
+ - **cargo-watch**: 8.5.x - File watcher
89
+ - **cargo-audit**: 0.21.x - Security audit
56
90
 
57
- **Best Practices**:
58
- - File ≤300 LOC, function ≤50 LOC
59
- - Prefer immutable bindings (let vs let mut)
60
- - Use iterators over manual loops
61
- - Avoid `unwrap()` in production code, use proper error handling
91
+ ## Ecosystem Overview
92
+
93
+ ### Project Setup (2025 Best Practice)
62
94
 
63
- ## Examples
64
95
  ```bash
65
- cargo test && cargo clippy -- -D warnings
96
+ # Modern Rust project with workspace structure
97
+ cargo new my-rust-project --bin
98
+ cd my-rust-project
99
+
100
+ # Create workspace structure
101
+ mkdir -p crates/{common,server,client}
102
+ mkdir -p src/{bin,lib}
103
+ mkdir -p tests/{integration,unit}
104
+ mkdir -p benches
105
+ mkdir -p examples
106
+
107
+ # Initialize workspace
108
+ echo '[workspace]
109
+ members = [
110
+ "crates/common",
111
+ "crates/server",
112
+ "crates/client",
113
+ ]' > Cargo.toml
114
+
115
+ # Add workspace crates
116
+ cargo new --lib crates/common
117
+ cargo new --lib crates/server
118
+ cargo new --lib crates/client
119
+
120
+ # Install development tools
121
+ cargo install cargo-watch
122
+ cargo install cargo-audit
123
+ cargo install cargo-expand
124
+ cargo install cargo-flamegraph
125
+ ```
126
+
127
+ ### Modern Project Structure
128
+
129
+ ```
130
+ my-rust-project/
131
+ ├── Cargo.toml # Workspace configuration
132
+ ├── Cargo.lock # Lock file
133
+ ├── rust-toolchain.toml # Toolchain specification
134
+ ├── .clippy.toml # Clippy configuration
135
+ ├── .rustfmt.toml # Rustfmt configuration
136
+ ├── deny.toml # Dependency deny list
137
+ ├── crates/
138
+ │ ├── common/ # Shared utilities
139
+ │ │ ├── Cargo.toml
140
+ │ │ └── src/
141
+ │ ├── server/ # Server application
142
+ │ │ ├── Cargo.toml
143
+ │ │ └── src/
144
+ │ └── client/ # Client library
145
+ │ ├── Cargo.toml
146
+ │ └── src/
147
+ ├── src/
148
+ │ ├── bin/ # Binary entry points
149
+ │ └── lib/ # Main library code
150
+ ├── tests/
151
+ │ ├── integration/ # Integration tests
152
+ │ └── unit/ # Unit tests
153
+ ├── benches/ # Performance benchmarks
154
+ ├── examples/ # Example usage
155
+ ├── docs/ # Documentation
156
+ └── scripts/ # Build and utility scripts
157
+ ```
158
+
159
+ ## Modern Rust Patterns
160
+
161
+ ### Error Handling with `thiserror` and `anyhow`
162
+
163
+ ```rust
164
+ // src/error.rs
165
+ use thiserror::Error;
166
+
167
+ #[derive(Error, Debug)]
168
+ pub enum AppError {
169
+ #[error("Database error: {0}")]
170
+ Database(#[from] sqlx::Error),
171
+
172
+ #[error("Validation error: {message}")]
173
+ Validation { message: String },
174
+
175
+ #[error("Not found: {entity} with id {id}")]
176
+ NotFound { entity: String, id: String },
177
+
178
+ #[error("Authentication failed")]
179
+ Authentication,
180
+
181
+ #[error("Authorization denied for {action}")]
182
+ Authorization { action: String },
183
+
184
+ #[error("Internal server error: {0}")]
185
+ Internal(#[from] anyhow::Error),
186
+ }
187
+
188
+ pub type Result<T> = std::result::Result<T, AppError>;
189
+
190
+ // Usage in application code
191
+ use anyhow::Context;
192
+
193
+ pub async fn get_user(id: &str) -> Result<User> {
194
+ let user = sqlx::query_as!(
195
+ User,
196
+ "SELECT * FROM users WHERE id = ?",
197
+ id
198
+ )
199
+ .fetch_one(&pool)
200
+ .await
201
+ .with_context(|| format!("Failed to fetch user with id: {}", id))?;
202
+
203
+ Ok(user)
204
+ }
205
+ ```
206
+
207
+ ### Async Programming with Tokio
208
+
209
+ ```rust
210
+ // src/services/user_service.rs
211
+ use tokio::sync::{RwLock, broadcast};
212
+ use std::sync::Arc;
213
+ use uuid::Uuid;
214
+
215
+ pub struct UserService {
216
+ users: Arc<RwLock<std::collections::HashMap<Uuid, User>>>,
217
+ event_tx: broadcast::Sender<UserEvent>,
218
+ }
219
+
220
+ impl UserService {
221
+ pub fn new() -> Self {
222
+ let (event_tx, _) = broadcast::channel(1000);
223
+ Self {
224
+ users: Arc::new(RwLock::new(std::collections::HashMap::new())),
225
+ event_tx,
226
+ }
227
+ }
228
+
229
+ pub async fn create_user(&self, user_data: CreateUserRequest) -> Result<User> {
230
+ let user_id = Uuid::new_v4();
231
+ let user = User {
232
+ id: user_id,
233
+ email: user_data.email.clone(),
234
+ name: user_data.name,
235
+ created_at: chrono::Utc::now(),
236
+ };
237
+
238
+ // Insert into user store
239
+ {
240
+ let mut users = self.users.write().await;
241
+ users.insert(user_id, user.clone());
242
+ }
243
+
244
+ // Emit event
245
+ let _ = self.event_tx.send(UserEvent::Created(user.clone()));
246
+
247
+ Ok(user)
248
+ }
249
+
250
+ pub async fn get_user(&self, user_id: Uuid) -> Option<User> {
251
+ let users = self.users.read().await;
252
+ users.get(&user_id).cloned()
253
+ }
254
+
255
+ pub async fn list_users(&self) -> Vec<User> {
256
+ let users = self.users.read().await;
257
+ users.values().cloned().collect()
258
+ }
259
+
260
+ pub fn subscribe_events(&self) -> broadcast::Receiver<UserEvent> {
261
+ self.event_tx.subscribe()
262
+ }
263
+ }
264
+
265
+ #[derive(Debug, Clone)]
266
+ pub enum UserEvent {
267
+ Created(User),
268
+ Updated(User),
269
+ Deleted { id: Uuid },
270
+ }
271
+
272
+ // Concurrent processing example
273
+ pub async fn process_users_concurrently(
274
+ user_service: Arc<UserService>,
275
+ users: Vec<User>,
276
+ ) -> Vec<Result<ProcessedUser>> {
277
+ let semaphore = Arc::new(tokio::sync::Semaphore::new(10)); // Limit concurrency
278
+
279
+ let tasks: Vec<_> = users
280
+ .into_iter()
281
+ .map(|user| {
282
+ let user_service = user_service.clone();
283
+ let semaphore = semaphore.clone();
284
+
285
+ tokio::spawn(async move {
286
+ let _permit = semaphore.acquire().await.unwrap();
287
+ process_single_user(&user_service, user).await
288
+ })
289
+ })
290
+ .collect();
291
+
292
+ let results = futures::future::join_all(tasks).await;
293
+ results.into_iter().map(|r| r.unwrap()).collect()
294
+ }
295
+ ```
296
+
297
+ ### Web Service with Axum
298
+
299
+ ```rust
300
+ // src/main.rs
301
+ use axum::{
302
+ extract::{Path, State},
303
+ http::StatusCode,
304
+ response::IntoResponse,
305
+ routing::{get, post},
306
+ Json, Router,
307
+ };
308
+ use serde::{Deserialize, Serialize};
309
+ use std::net::SocketAddr;
310
+ use tower::ServiceBuilder;
311
+ use tower_http::{
312
+ cors::{Any, CorsLayer},
313
+ trace::TraceLayer,
314
+ };
315
+ use tracing::{info, Level};
316
+ use tracing_subscriber;
317
+
318
+ mod error;
319
+ mod handlers;
320
+ mod models;
321
+ mod services;
322
+ mod middleware;
323
+
324
+ use error::AppError;
325
+ use handlers::{create_user, get_user, health_check};
326
+ use services::UserService;
327
+
328
+ #[derive(Clone)]
329
+ pub struct AppState {
330
+ pub user_service: Arc<UserService>,
331
+ }
332
+
333
+ #[tokio::main]
334
+ async fn main() -> Result<(), Box<dyn std::error::Error>> {
335
+ // Initialize tracing
336
+ tracing_subscriber::fmt()
337
+ .with_max_level(Level::INFO)
338
+ .init();
339
+
340
+ // Initialize services
341
+ let user_service = Arc::new(UserService::new());
342
+ let app_state = AppState { user_service };
343
+
344
+ // Build application
345
+ let app = Router::new()
346
+ // Routes
347
+ .route("/health", get(health_check))
348
+ .route("/users", post(create_user))
349
+ .route("/users/:id", get(get_user))
350
+ // Middleware
351
+ .layer(
352
+ ServiceBuilder::new()
353
+ .layer(TraceLayer::new_for_http())
354
+ .layer(CorsLayer::new().allow_origin(Any))
355
+ .layer(axum::middleware::from_fn(middleware::request_logging)),
356
+ )
357
+ .with_state(app_state);
358
+
359
+ // Run server
360
+ let addr = SocketAddr::from(([0, 0, 0, 0], 8080));
361
+ info!("Server listening on {}", addr);
362
+
363
+ axum::Server::bind(&addr)
364
+ .serve(app.into_make_service())
365
+ .await?;
366
+
367
+ Ok(())
368
+ }
369
+
370
+ // src/handlers/user.rs
371
+ use axum::{extract::{Path, State}, Json};
372
+ use uuid::Uuid;
373
+ use crate::{error::AppError, models::User, services::UserService, AppState};
374
+
375
+ pub async fn create_user(
376
+ State(state): State<AppState>,
377
+ Json(payload): Json<CreateUserRequest>,
378
+ ) -> Result<Json<User>, AppError> {
379
+ let user = state.user_service.create_user(payload).await?;
380
+ Ok(Json(user))
381
+ }
382
+
383
+ pub async fn get_user(
384
+ State(state): State<AppState>,
385
+ Path(user_id): Path<Uuid>,
386
+ ) -> Result<Json<User>, AppError> {
387
+ let user = state
388
+ .user_service
389
+ .get_user(user_id)
390
+ .await
391
+ .ok_or(AppError::NotFound {
392
+ entity: "User".to_string(),
393
+ id: user_id.to_string(),
394
+ })?;
395
+
396
+ Ok(Json(user))
397
+ }
398
+
399
+ pub async fn health_check() -> impl IntoResponse {
400
+ Json(serde_json::json!({
401
+ "status": "healthy",
402
+ "timestamp": chrono::Utc::now(),
403
+ }))
404
+ }
405
+ ```
406
+
407
+ ## Performance Optimization
408
+
409
+ ### Memory Management and Zero-Copy Patterns
410
+
411
+ ```rust
412
+ // src/processing/data_processor.rs
413
+ use bytes::{Bytes, BytesMut, BufMut};
414
+ use std::io::{self, Read};
415
+
416
+ pub struct DataProcessor {
417
+ buffer: BytesMut,
418
+ }
419
+
420
+ impl DataProcessor {
421
+ pub fn new() -> Self {
422
+ Self {
423
+ buffer: BytesMut::with_capacity(8192),
424
+ }
425
+ }
426
+
427
+ // Zero-copy data processing
428
+ pub fn process_stream<R: Read>(&mut self, mut reader: R) -> io::Result<ProcessedData> {
429
+ self.buffer.clear();
430
+
431
+ // Read data into buffer
432
+ let bytes_read = reader.read(&mut self.buffer)?;
433
+ if bytes_read == 0 {
434
+ return Ok(ProcessedData::empty());
435
+ }
436
+
437
+ // Process without copying
438
+ let data = self.buffer.split().freeze();
439
+ self.process_bytes(data)
440
+ }
441
+
442
+ fn process_bytes(&self, data: Bytes) -> io::Result<ProcessedData> {
443
+ let mut records = Vec::new();
444
+
445
+ // Process data without allocations
446
+ for line in data.split(|&b| b == b'\n') {
447
+ if line.is_empty() {
448
+ continue;
449
+ }
450
+
451
+ let record = self.parse_record(line)?;
452
+ records.push(record);
453
+ }
454
+
455
+ Ok(ProcessedData { records })
456
+ }
457
+
458
+ fn parse_record(&self, line: &[u8]) -> io::Result<Record> {
459
+ // Parse using slices instead of String allocations
460
+ let mut parts = line.split(|&b| b == b',');
461
+
462
+ let id_parts = parts.next().ok_or(io::ErrorKind::InvalidData)?;
463
+ let name_parts = parts.next().ok_or(io::ErrorKind::InvalidData)?;
464
+
465
+ Ok(Record {
466
+ id: std::str::from_utf8(id_parts)
467
+ .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid UTF-8"))?
468
+ .to_string(),
469
+ name: std::str::from_utf8(name_parts)
470
+ .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid UTF-8"))?
471
+ .to_string(),
472
+ })
473
+ }
474
+ }
475
+
476
+ // SIMD-optimized processing
477
+ #[cfg(target_arch = "x86_64")]
478
+ use std::arch::x86_64::*;
479
+
480
+ pub fn fast_checksum(data: &[u8]) -> u64 {
481
+ #[target_feature(enable = "avx2")]
482
+ unsafe {
483
+ if is_x86_feature_detected!("avx2") {
484
+ checksum_avx2(data)
485
+ } else {
486
+ checksum_scalar(data)
487
+ }
488
+ }
489
+ }
490
+
491
+ #[target_feature(enable = "avx2")]
492
+ unsafe fn checksum_avx2(data: &[u8]) -> u64 {
493
+ let chunks = data.chunks_exact(32);
494
+ let remainder = chunks.remainder();
495
+
496
+ let mut sum = _mm256_setzero_si256();
497
+
498
+ for chunk in chunks {
499
+ let chunk = _mm256_loadu_si256(chunk.as_ptr() as *const __m256i);
500
+ sum = _mm256_add_epi64(sum, _mm256_sad_epu8(chunk, _mm256_setzero_si256()));
501
+ }
502
+
503
+ let mut result = _mm256_extract_epi128(sum, 1) as u64 + _mm256_extract_epi128(sum, 0) as u64;
504
+
505
+ // Process remainder
506
+ for &byte in remainder {
507
+ result += byte as u64;
508
+ }
509
+
510
+ result
511
+ }
512
+
513
+ fn checksum_scalar(data: &[u8]) -> u64 {
514
+ data.iter().map(|&b| b as u64).sum()
515
+ }
516
+ ```
517
+
518
+ ### Efficient Data Structures
519
+
520
+ ```rust
521
+ // src/datastructures/high_performance_map.rs
522
+ use std::collections::HashMap;
523
+ use std::hash::{Hash, Hasher};
524
+
525
+ // Custom hash map optimized for string keys
526
+ pub struct StringKeyMap<V> {
527
+ inner: HashMap<Box<str>, V>,
528
+ key_pool: Vec<Box<str>>,
529
+ }
530
+
531
+ impl<V> StringKeyMap<V> {
532
+ pub fn new() -> Self {
533
+ Self {
534
+ inner: HashMap::new(),
535
+ key_pool: Vec::new(),
536
+ }
537
+ }
538
+
539
+ pub fn insert(&mut self, key: &str, value: V) -> Option<V> {
540
+ // Intern the key to avoid allocations for duplicate keys
541
+ let interned_key = self.intern_key(key);
542
+ self.inner.insert(interned_key, value)
543
+ }
544
+
545
+ pub fn get(&self, key: &str) -> Option<&V> {
546
+ self.inner.get(key)
547
+ }
548
+
549
+ pub fn get_mut(&mut self, key: &str) -> Option<&mut V> {
550
+ self.inner.get_mut(key)
551
+ }
552
+
553
+ pub fn remove(&mut self, key: &str) -> Option<V> {
554
+ self.inner.remove(key)
555
+ }
556
+
557
+ fn intern_key(&mut self, key: &str) -> Box<str> {
558
+ // Simple string interning - in production, use a proper interner
559
+ for interned in &self.key_pool {
560
+ if interned.as_ref() == key {
561
+ return interned.clone();
562
+ }
563
+ }
564
+
565
+ let interned: Box<str> = key.into();
566
+ self.key_pool.push(interned.clone());
567
+ interned
568
+ }
569
+ }
570
+
571
+ // High-performance ring buffer
572
+ pub struct RingBuffer<T> {
573
+ buffer: Vec<Option<T>>,
574
+ head: usize,
575
+ tail: usize,
576
+ size: usize,
577
+ capacity: usize,
578
+ }
579
+
580
+ impl<T> RingBuffer<T> {
581
+ pub fn new(capacity: usize) -> Self {
582
+ Self {
583
+ buffer: vec![None; capacity],
584
+ head: 0,
585
+ tail: 0,
586
+ size: 0,
587
+ capacity,
588
+ }
589
+ }
590
+
591
+ pub fn push(&mut self, item: T) -> bool {
592
+ if self.size >= self.capacity {
593
+ return false; // Buffer full
594
+ }
595
+
596
+ self.buffer[self.tail] = Some(item);
597
+ self.tail = (self.tail + 1) % self.capacity;
598
+ self.size += 1;
599
+ true
600
+ }
601
+
602
+ pub fn pop(&mut self) -> Option<T> {
603
+ if self.size == 0 {
604
+ return None;
605
+ }
606
+
607
+ let item = self.buffer[self.head].take();
608
+ self.head = (self.head + 1) % self.capacity;
609
+ self.size -= 1;
610
+ item
611
+ }
612
+
613
+ pub fn is_empty(&self) -> bool {
614
+ self.size == 0
615
+ }
616
+
617
+ pub fn is_full(&self) -> bool {
618
+ self.size == self.capacity
619
+ }
620
+
621
+ pub fn len(&self) -> usize {
622
+ self.size
623
+ }
624
+
625
+ pub fn capacity(&self) -> usize {
626
+ self.capacity
627
+ }
628
+ }
66
629
  ```
67
630
 
68
- ## Inputs
69
- - Language-specific source directories (e.g. `src/`, `app/`).
70
- - Language-specific build/test configuration files (e.g. `package.json`, `pyproject.toml`, `go.mod`).
71
- - Relevant test suites and sample data.
631
+ ## Testing Strategies
72
632
 
73
- ## Outputs
74
- - Test/lint execution plan tailored to the selected language.
75
- - List of key language idioms and review checkpoints.
633
+ ### Comprehensive Unit Testing
634
+
635
+ ```rust
636
+ // tests/unit/user_service_test.rs
637
+ use tokio_test;
638
+ use uuid::Uuid;
639
+ use crate::services::{UserService, CreateUserRequest};
640
+ use crate::models::User;
641
+
642
+ #[tokio::test]
643
+ async fn test_create_user() {
644
+ let service = UserService::new();
645
+ let request = CreateUserRequest {
646
+ email: "test@example.com".to_string(),
647
+ name: "Test User".to_string(),
648
+ };
649
+
650
+ let user = service.create_user(request).await.unwrap();
651
+
652
+ assert!(!user.id.to_string().is_empty());
653
+ assert_eq!(user.email, "test@example.com");
654
+ assert_eq!(user.name, "Test User");
655
+ assert!(user.created_at <= chrono::Utc::now());
656
+ }
657
+
658
+ #[tokio::test]
659
+ async fn test_get_user() {
660
+ let service = UserService::new();
661
+ let request = CreateUserRequest {
662
+ email: "test@example.com".to_string(),
663
+ name: "Test User".to_string(),
664
+ };
665
+
666
+ let created_user = service.create_user(request).await.unwrap();
667
+ let retrieved_user = service.get_user(created_user.id).await.unwrap();
668
+
669
+ assert_eq!(created_user.id, retrieved_user.id);
670
+ assert_eq!(created_user.email, retrieved_user.email);
671
+ assert_eq!(created_user.name, retrieved_user.name);
672
+ }
673
+
674
+ #[tokio::test]
675
+ async fn test_get_nonexistent_user() {
676
+ let service = UserService::new();
677
+ let nonexistent_id = Uuid::new_v4();
678
+
679
+ let user = service.get_user(nonexistent_id).await;
680
+ assert!(user.is_none());
681
+ }
682
+
683
+ #[tokio::test]
684
+ async fn test_create_user_duplicate_email() {
685
+ let service = UserService::new();
686
+ let request = CreateUserRequest {
687
+ email: "duplicate@example.com".to_string(),
688
+ name: "User 1".to_string(),
689
+ };
690
+
691
+ // Create first user
692
+ service.create_user(request.clone()).await.unwrap();
693
+
694
+ // Try to create second user with same email
695
+ let result = service.create_user(request).await;
696
+ assert!(result.is_err());
697
+ }
698
+
699
+ #[tokio::test]
700
+ async fn test_user_events() {
701
+ let service = UserService::new();
702
+ let mut event_rx = service.subscribe_events();
703
+
704
+ let request = CreateUserRequest {
705
+ email: "events@example.com".to_string(),
706
+ name: "Event User".to_string(),
707
+ };
708
+
709
+ let created_user = service.create_user(request).await.unwrap();
710
+
711
+ // Should receive UserCreated event
712
+ let event = event_rx.recv().await.unwrap();
713
+ match event {
714
+ UserEvent::Created(user) => {
715
+ assert_eq!(user.id, created_user.id);
716
+ assert_eq!(user.email, created_user.email);
717
+ }
718
+ _ => panic!("Expected UserCreated event"),
719
+ }
720
+ }
721
+
722
+ // Property-based testing with proptest
723
+ use proptest::prelude::*;
724
+
725
+ proptest! {
726
+ #[test]
727
+ fn test_user_email_validation(email in "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}") {
728
+ prop_assert!(is_valid_email(&email));
729
+ }
730
+
731
+ #[test]
732
+ fn test_ring_buffer(
733
+ items in prop::collection::vec(any::<i32>(), 1..100),
734
+ capacity in 1usize..=100
735
+ ) {
736
+ let mut buffer = RingBuffer::new(capacity);
737
+
738
+ for &item in &items {
739
+ if !buffer.push(item) {
740
+ break; // Buffer full
741
+ }
742
+ }
743
+
744
+ let popped_count = std::cmp::min(items.len(), capacity);
745
+ for (i, &expected_item) in items.iter().take(popped_count).enumerate() {
746
+ let popped = buffer.pop().unwrap();
747
+ prop_assert_eq!(popped, expected_item);
748
+ }
749
+
750
+ prop_assert!(buffer.is_empty());
751
+ }
752
+ }
753
+
754
+ fn is_valid_email(email: &str) -> bool {
755
+ email.contains('@') && email.contains('.')
756
+ }
757
+ ```
758
+
759
+ ### Integration Testing with TestContainers
760
+
761
+ ```rust
762
+ // tests/integration/api_test.rs
763
+ use axum_test::TestServer;
764
+ use serde_json::json;
765
+ use sqlx::PgPool;
766
+ use std::sync::Arc;
767
+ use tempfile::TempDir;
768
+ use tokio::time::{timeout, Duration};
769
+
770
+ use my_app::{create_app, AppState};
771
+ use my_app::services::{UserService, DatabaseUserService};
772
+
773
+ struct TestApp {
774
+ server: TestServer,
775
+ pool: PgPool,
776
+ _temp_dir: TempDir,
777
+ }
778
+
779
+ async fn setup_test_app() -> TestApp {
780
+ // Create temporary directory for test database
781
+ let temp_dir = TempDir::new().unwrap();
782
+
783
+ // Setup test database
784
+ let database_url = format!("sqlite:{}", temp_dir.path().join("test.db").display());
785
+ let pool = sqlx::SqlitePool::connect(&database_url).await.unwrap();
786
+
787
+ // Run migrations
788
+ sqlx::migrate!("./migrations").run(&pool).await.unwrap();
789
+
790
+ // Create services
791
+ let db_service = DatabaseUserService::new(pool.clone());
792
+ let user_service = Arc::new(UserService::new(Box::new(db_service)));
793
+
794
+ let app_state = AppState { user_service };
795
+ let app = create_app(app_state);
796
+
797
+ let server = TestServer::new(app).unwrap();
798
+
799
+ TestApp {
800
+ server,
801
+ pool,
802
+ _temp_dir: temp_dir,
803
+ }
804
+ }
805
+
806
+ #[tokio::test]
807
+ async fn test_user_lifecycle() {
808
+ let test_app = setup_test_app().await;
809
+
810
+ // Create user
811
+ let create_response = test_app
812
+ .server
813
+ .post("/users")
814
+ .json(&json!({
815
+ "email": "integration@example.com",
816
+ "name": "Integration User"
817
+ }))
818
+ .await;
819
+
820
+ create_response.assert_status_ok();
821
+
822
+ let user: User = create_response.json();
823
+ assert_eq!(user.email, "integration@example.com");
824
+ assert_eq!(user.name, "Integration User");
825
+
826
+ // Get user
827
+ let get_response = test_app
828
+ .server
829
+ .get(&format!("/users/{}", user.id))
830
+ .await;
831
+
832
+ get_response.assert_status_ok();
833
+
834
+ let retrieved_user: User = get_response.json();
835
+ assert_eq!(retrieved_user.id, user.id);
836
+ assert_eq!(retrieved_user.email, user.email);
837
+
838
+ // List users
839
+ let list_response = test_app.server.get("/users").await;
840
+ list_response.assert_status_ok();
841
+
842
+ let users: Vec<User> = list_response.json();
843
+ assert_eq!(users.len(), 1);
844
+ assert_eq!(users[0].id, user.id);
845
+ }
846
+
847
+ #[tokio::test]
848
+ async fn test_concurrent_user_creation() {
849
+ let test_app = setup_test_app().await;
850
+
851
+ let mut handles = vec![];
852
+
853
+ for i in 0..10 {
854
+ let server = test_app.server.clone();
855
+ let handle = tokio::spawn(async move {
856
+ server
857
+ .post("/users")
858
+ .json(&json!({
859
+ "email": format!("user{}@example.com", i),
860
+ "name": format!("User {}", i)
861
+ }))
862
+ .await
863
+ });
864
+ handles.push(handle);
865
+ }
866
+
867
+ let responses = futures::future::join_all(handles).await;
868
+
869
+ for response in responses {
870
+ let response = response.unwrap();
871
+ response.assert_status_ok();
872
+ }
873
+
874
+ // Verify all users were created
875
+ let list_response = test_app.server.get("/users").await;
876
+ list_response.assert_status_ok();
877
+
878
+ let users: Vec<User> = list_response.json();
879
+ assert_eq!(users.len(), 10);
880
+ }
881
+
882
+ #[tokio::test]
883
+ async fn test_request_timeout() {
884
+ let test_app = setup_test_app().await;
885
+
886
+ // Simulate slow operation
887
+ let response = test_app
888
+ .server
889
+ .post("/slow-endpoint")
890
+ .add_header("x-delay", "5000") // 5 second delay
891
+ .await;
892
+
893
+ // Should timeout before response
894
+ let result = timeout(Duration::from_secs(1), response).await;
895
+ assert!(result.is_err());
896
+ }
897
+ ```
76
898
 
77
- ## Failure Modes
78
- - When the language runtime or package manager is not installed.
79
- - When the main language cannot be determined in a multilingual project.
899
+ ## Security Best Practices
80
900
 
81
- ## Dependencies
82
- - Access to the project file is required using the Read/Grep tool.
83
- - When used with `Skill("moai-foundation-langs")`, it is easy to share cross-language conventions.
901
+ ### Input Validation and Sanitization
84
902
 
85
- ## References
86
- - Rust Project Developers. "The Rust Programming Language." https://doc.rust-lang.org/book/ (accessed 2025-03-29).
87
- - Rust Project Developers. "Clippy." https://doc.rust-lang.org/clippy/ (accessed 2025-03-29).
903
+ ```rust
904
+ // src/security/validation.rs
905
+ use regex::Regex;
906
+ use std::collections::HashSet;
907
+ use once_cell::sync::Lazy;
88
908
 
89
- ## Changelog
90
- - 2025-03-29: Input/output/failure response/reference information for each language has been specified.
909
+ static EMAIL_REGEX: Lazy<Regex> = Lazy::new(|| {
910
+ Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$").unwrap()
911
+ });
91
912
 
92
- ## Works well with
913
+ static PASSWORD_REGEX: Lazy<Regex> = Lazy::new(|| {
914
+ Regex::new(r"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$").unwrap()
915
+ });
916
+
917
+ static SQL_INJECTION_PATTERNS: Lazy<Vec<Regex>> = Lazy::new(|| {
918
+ vec![
919
+ Regex::new(r"(?i)(union|select|insert|update|delete|drop|create|alter)").unwrap(),
920
+ Regex::new(r"(?i)(script|javascript|vbscript|onload|onerror)").unwrap(),
921
+ Regex::new(r"(--|;|\/\*|\*\/)").unwrap(),
922
+ ]
923
+ });
924
+
925
+ pub struct Validator;
926
+
927
+ impl Validator {
928
+ pub fn validate_email(email: &str) -> Result<(), ValidationError> {
929
+ if email.len() > 254 {
930
+ return Err(ValidationError::EmailTooLong);
931
+ }
932
+
933
+ if !EMAIL_REGEX.is_match(email) {
934
+ return Err(ValidationError::InvalidEmailFormat);
935
+ }
936
+
937
+ Ok(())
938
+ }
939
+
940
+ pub fn validate_password(password: &str) -> Result<(), ValidationError> {
941
+ if password.len() < 8 {
942
+ return Err(ValidationError::PasswordTooShort);
943
+ }
944
+
945
+ if password.len() > 128 {
946
+ return Err(ValidationError::PasswordTooLong);
947
+ }
948
+
949
+ if !PASSWORD_REGEX.is_match(password) {
950
+ return Err(ValidationError::WeakPassword);
951
+ }
952
+
953
+ // Check for common weak passwords
954
+ if Self::is_common_password(password) {
955
+ return Err(ValidationError::CommonPassword);
956
+ }
957
+
958
+ Ok(())
959
+ }
960
+
961
+ pub fn sanitize_input(input: &str) -> String {
962
+ let mut sanitized = String::with_capacity(input.len());
963
+
964
+ for ch in input.chars() {
965
+ match ch {
966
+ // Allow safe characters
967
+ 'a'..='z' | 'A'..='Z' | '0'..='9' | ' ' | '-' | '_' | '.' | '@' => {
968
+ sanitized.push(ch);
969
+ }
970
+ // Replace dangerous characters
971
+ '<' => sanitized.push_str("&lt;"),
972
+ '>' => sanitized.push_str("&gt;"),
973
+ '&' => sanitized.push_str("&amp;"),
974
+ '"' => sanitized.push_str("&quot;"),
975
+ '\'' => sanitized.push_str("&#x27;"),
976
+ _ => {
977
+ // Skip other characters
978
+ }
979
+ }
980
+ }
981
+
982
+ sanitized.trim().to_string()
983
+ }
984
+
985
+ pub fn detect_sql_injection(input: &str) -> bool {
986
+ let lowercase_input = input.to_lowercase();
987
+
988
+ for pattern in SQL_INJECTION_PATTERNS.iter() {
989
+ if pattern.is_match(&lowercase_input) {
990
+ return true;
991
+ }
992
+ }
993
+
994
+ false
995
+ }
996
+
997
+ fn is_common_password(password: &str) -> bool {
998
+ static COMMON_PASSWORDS: Lazy<HashSet<&'static str>> = Lazy::new(|| {
999
+ vec![
1000
+ "password", "123456", "123456789", "12345678", "12345",
1001
+ "1234567", "1234567890", "qwerty", "abc123", "password123",
1002
+ ].into_iter().collect()
1003
+ });
1004
+
1005
+ COMMON_PASSWORDS.contains(password.to_lowercase().as_str())
1006
+ }
1007
+ }
1008
+
1009
+ #[derive(Debug, thiserror::Error)]
1010
+ pub enum ValidationError {
1011
+ #[error("Email is too long (max 254 characters)")]
1012
+ EmailTooLong,
1013
+
1014
+ #[error("Invalid email format")]
1015
+ InvalidEmailFormat,
1016
+
1017
+ #[error("Password is too short (min 8 characters)")]
1018
+ PasswordTooShort,
1019
+
1020
+ #[error("Password is too long (max 128 characters)")]
1021
+ PasswordTooLong,
1022
+
1023
+ #[error("Password is too weak")]
1024
+ WeakPassword,
1025
+
1026
+ #[error("Password is too common")]
1027
+ CommonPassword,
1028
+ }
1029
+
1030
+ // Rate limiting
1031
+ use std::collections::HashMap;
1032
+ use std::time::{Duration, Instant};
1033
+ use tokio::sync::RwLock;
1034
+
1035
+ pub struct RateLimiter {
1036
+ requests: Arc<RwLock<HashMap<String, Vec<Instant>>>>,
1037
+ max_requests: usize,
1038
+ window: Duration,
1039
+ }
1040
+
1041
+ impl RateLimiter {
1042
+ pub fn new(max_requests: usize, window: Duration) -> Self {
1043
+ Self {
1044
+ requests: Arc::new(RwLock::new(HashMap::new())),
1045
+ max_requests,
1046
+ window,
1047
+ }
1048
+ }
1049
+
1050
+ pub async fn is_allowed(&self, key: &str) -> bool {
1051
+ let now = Instant::now();
1052
+ let mut requests = self.requests.write().await;
1053
+
1054
+ let user_requests = requests.entry(key.to_string()).or_insert_with(Vec::new);
1055
+
1056
+ // Remove old requests outside the window
1057
+ user_requests.retain(|&timestamp| now.duration_since(timestamp) < self.window);
1058
+
1059
+ if user_requests.len() >= self.max_requests {
1060
+ return false;
1061
+ }
1062
+
1063
+ user_requests.push(now);
1064
+ true
1065
+ }
1066
+ }
1067
+ ```
1068
+
1069
+ ### Authentication and Authorization
1070
+
1071
+ ```rust
1072
+ // src/security/auth.rs
1073
+ use argon2::{password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString}, Argon2};
1074
+ use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation};
1075
+ use serde::{Deserialize, Serialize};
1076
+ use std::time::{Duration, SystemTime, UNIX_EPOCH};
1077
+ use uuid::Uuid;
1078
+
1079
+ #[derive(Debug, Serialize, Deserialize)]
1080
+ pub struct Claims {
1081
+ pub sub: String, // Subject (user ID)
1082
+ pub email: String,
1083
+ pub role: String,
1084
+ pub exp: usize, // Expiration time
1085
+ pub iat: usize, // Issued at
1086
+ }
1087
+
1088
+ pub struct AuthService {
1089
+ jwt_secret: String,
1090
+ token_expiry: Duration,
1091
+ }
1092
+
1093
+ impl AuthService {
1094
+ pub fn new(jwt_secret: String, token_expiry: Duration) -> Self {
1095
+ Self {
1096
+ jwt_secret,
1097
+ token_expiry,
1098
+ }
1099
+ }
1100
+
1101
+ pub fn hash_password(password: &str) -> Result<String, AuthError> {
1102
+ let salt = SaltString::generate(&mut OsRng);
1103
+ let argon2 = Argon2::default();
1104
+
1105
+ let password_hash = argon2
1106
+ .hash_password(password.as_bytes(), &salt)
1107
+ .map_err(|e| AuthError::PasswordHashing(e.to_string()))?;
1108
+
1109
+ Ok(password_hash.to_string())
1110
+ }
1111
+
1112
+ pub fn verify_password(password: &str, hash: &str) -> Result<bool, AuthError> {
1113
+ let parsed_hash = PasswordHash::new(hash)
1114
+ .map_err(|e| AuthError::InvalidHash(e.to_string()))?;
1115
+
1116
+ let argon2 = Argon2::default();
1117
+
1118
+ match argon2.verify_password(password.as_bytes(), &parsed_hash) {
1119
+ Ok(_) => Ok(true),
1120
+ Err(argon2::password_hash::Error::Password) => Ok(false),
1121
+ Err(e) => Err(AuthError::PasswordHashing(e.to_string())),
1122
+ }
1123
+ }
1124
+
1125
+ pub fn generate_token(&self, user_id: &str, email: &str, role: &str) -> Result<String, AuthError> {
1126
+ let now = SystemTime::now()
1127
+ .duration_since(UNIX_EPOCH)
1128
+ .map_err(|e| AuthError::TokenGeneration(e.to_string()))?;
1129
+
1130
+ let claims = Claims {
1131
+ sub: user_id.to_string(),
1132
+ email: email.to_string(),
1133
+ role: role.to_string(),
1134
+ exp: (now + self.token_expiry).as_secs() as usize,
1135
+ iat: now.as_secs() as usize,
1136
+ };
1137
+
1138
+ let token = encode(
1139
+ &Header::default(),
1140
+ &claims,
1141
+ &EncodingKey::from_secret(self.jwt_secret.as_bytes()),
1142
+ )
1143
+ .map_err(|e| AuthError::TokenGeneration(e.to_string()))?;
1144
+
1145
+ Ok(token)
1146
+ }
1147
+
1148
+ pub fn validate_token(&self, token: &str) -> Result<Claims, AuthError> {
1149
+ let validation = Validation::default();
1150
+ let decoded = decode::<Claims>(
1151
+ token,
1152
+ &DecodingKey::from_secret(self.jwt_secret.as_bytes()),
1153
+ &validation,
1154
+ )
1155
+ .map_err(|_| AuthError::InvalidToken)?;
1156
+
1157
+ Ok(decoded.claims)
1158
+ }
1159
+
1160
+ pub fn refresh_token(&self, claims: &Claims) -> Result<String, AuthError> {
1161
+ self.generate_token(&claims.sub, &claims.email, &claims.role)
1162
+ }
1163
+ }
1164
+
1165
+ #[derive(Debug, thiserror::Error)]
1166
+ pub enum AuthError {
1167
+ #[error("Password hashing failed: {0}")]
1168
+ PasswordHashing(String),
1169
+
1170
+ #[error("Invalid password hash: {0}")]
1171
+ InvalidHash(String),
1172
+
1173
+ #[error("Token generation failed: {0}")]
1174
+ TokenGeneration(String),
1175
+
1176
+ #[error("Invalid token")]
1177
+ InvalidToken,
1178
+
1179
+ #[error("Token expired")]
1180
+ TokenExpired,
1181
+ }
1182
+
1183
+ // Authorization middleware for axum
1184
+ use axum::{
1185
+ extract::{Request, State},
1186
+ http::{header::AUTHORIZATION, StatusCode},
1187
+ middleware::Next,
1188
+ response::Response,
1189
+ };
1190
+ use std::sync::Arc;
1191
+
1192
+ pub async fn auth_middleware(
1193
+ State(auth_service): State<Arc<AuthService>>,
1194
+ mut request: Request,
1195
+ next: Next,
1196
+ ) -> Result<Response, StatusCode> {
1197
+ let auth_header = request
1198
+ .headers()
1199
+ .get(AUTHORIZATION)
1200
+ .and_then(|header| header.to_str().ok())
1201
+ .and_then(|header| header.strip_prefix("Bearer "));
1202
+
1203
+ let token = match auth_header {
1204
+ Some(token) => token,
1205
+ None => return Err(StatusCode::UNAUTHORIZED),
1206
+ };
1207
+
1208
+ let claims = match auth_service.validate_token(token) {
1209
+ Ok(claims) => claims,
1210
+ Err(_) => return Err(StatusCode::UNAUTHORIZED),
1211
+ };
1212
+
1213
+ // Add claims to request extensions
1214
+ request.extensions_mut().insert(claims);
1215
+
1216
+ Ok(next.run(request).await)
1217
+ }
1218
+
1219
+ pub fn require_role(required_role: &'static str) -> impl Fn(Request, Next) -> Result<Response, StatusCode> {
1220
+ move |request: Request, next: Next| {
1221
+ let claims = request.extensions().get::<Claims>();
1222
+
1223
+ match claims {
1224
+ Some(claims) if claims.role == required_role => Ok(next.run(request)),
1225
+ Some(_) => Err(StatusCode::FORBIDDEN),
1226
+ None => Err(StatusCode::UNAUTHORIZED),
1227
+ }
1228
+ }
1229
+ }
1230
+ ```
1231
+
1232
+ ## Integration Patterns
1233
+
1234
+ ### gRPC Service Implementation
1235
+
1236
+ ```rust
1237
+ // src/grpc/user_service.rs
1238
+ use tonic::{transport::Server, Request, Response, Status, Code};
1239
+ use tonic_health::server::HealthReporter;
1240
+
1241
+ pub mod user {
1242
+ tonic::include_proto!("user");
1243
+ }
1244
+
1245
+ use user::{
1246
+ user_service_server::{UserService, UserServiceServer},
1247
+ CreateUserRequest, CreateUserResponse,
1248
+ GetUserRequest, GetUserResponse,
1249
+ User as GrpcUser,
1250
+ };
1251
+
1252
+ use crate::models::User;
1253
+ use crate::services::UserService as AppUserService;
1254
+ use crate::error::AppError;
1255
+
1256
+ pub struct GrpcUserService {
1257
+ app_service: Arc<AppUserService>,
1258
+ }
1259
+
1260
+ impl GrpcUserService {
1261
+ pub fn new(app_service: Arc<AppUserService>) -> Self {
1262
+ Self { app_service }
1263
+ }
1264
+ }
1265
+
1266
+ #[tonic::async_trait]
1267
+ impl UserService for GrpcUserService {
1268
+ async fn create_user(
1269
+ &self,
1270
+ request: Request<CreateUserRequest>,
1271
+ ) -> Result<Response<CreateUserResponse>, Status> {
1272
+ let req = request.into_inner();
1273
+
1274
+ let create_req = crate::services::CreateUserRequest {
1275
+ email: req.email,
1276
+ name: req.name,
1277
+ };
1278
+
1279
+ match self.app_service.create_user(create_req).await {
1280
+ Ok(user) => {
1281
+ let grpc_user = GrpcUser {
1282
+ id: user.id.to_string(),
1283
+ email: user.email,
1284
+ name: user.name,
1285
+ created_at: Some(user.created_at.into()),
1286
+ };
1287
+
1288
+ let response = CreateUserResponse { user: Some(grpc_user) };
1289
+ Ok(Response::new(response))
1290
+ }
1291
+ Err(e) => {
1292
+ let status = match e {
1293
+ AppError::Validation { .. } => Status::invalid_argument(e.to_string()),
1294
+ AppError::DuplicateEmail => Status::already_exists(e.to_string()),
1295
+ _ => Status::internal(e.to_string()),
1296
+ };
1297
+ Err(status)
1298
+ }
1299
+ }
1300
+ }
1301
+
1302
+ async fn get_user(
1303
+ &self,
1304
+ request: Request<GetUserRequest>,
1305
+ ) -> Result<Response<GetUserResponse>, Status> {
1306
+ let req = request.into_inner();
1307
+
1308
+ let user_id = Uuid::parse_str(&req.id)
1309
+ .map_err(|_| Status::invalid_argument("Invalid user ID"))?;
1310
+
1311
+ match self.app_service.get_user(user_id).await {
1312
+ Some(user) => {
1313
+ let grpc_user = GrpcUser {
1314
+ id: user.id.to_string(),
1315
+ email: user.email,
1316
+ name: user.name,
1317
+ created_at: Some(user.created_at.into()),
1318
+ };
1319
+
1320
+ let response = GetUserResponse { user: Some(grpc_user) };
1321
+ Ok(Response::new(response))
1322
+ }
1323
+ None => Err(Status::not_found("User not found")),
1324
+ }
1325
+ }
1326
+ }
1327
+
1328
+ // Server setup
1329
+ pub async fn run_grpc_server(
1330
+ addr: std::net::SocketAddr,
1331
+ user_service: Arc<AppUserService>,
1332
+ ) -> Result<(), Box<dyn std::error::Error>> {
1333
+ let grpc_service = GrpcUserService::new(user_service);
1334
+
1335
+ let (mut health_reporter, health_service) = tonic_health::server::health_reporter();
1336
+ health_reporter.set_serving::<UserServiceServer<GrpcUserService>>().await;
1337
+
1338
+ Server::builder()
1339
+ .add_service(health_service)
1340
+ .add_service(UserServiceServer::new(grpc_service))
1341
+ .serve(addr)
1342
+ .await?;
1343
+
1344
+ Ok(())
1345
+ }
1346
+ ```
1347
+
1348
+ ### Message Queue Integration
1349
+
1350
+ ```rust
1351
+ // src/messaging/kafka_producer.rs
1352
+ use rdkafka::{
1353
+ config::ClientConfig,
1354
+ producer::{FutureProducer, FutureRecord},
1355
+ Client as KafkaClient,
1356
+ };
1357
+ use serde::{Deserialize, Serialize};
1358
+ use std::time::Duration;
1359
+ use tokio::time::timeout;
1360
+
1361
+ #[derive(Debug, Serialize, Deserialize)]
1362
+ pub struct Event {
1363
+ pub id: String,
1364
+ pub event_type: String,
1365
+ pub data: serde_json::Value,
1366
+ pub timestamp: chrono::DateTime<chrono::Utc>,
1367
+ pub version: u32,
1368
+ }
1369
+
1370
+ pub struct EventProducer {
1371
+ producer: FutureProducer,
1372
+ }
1373
+
1374
+ impl EventProducer {
1375
+ pub fn new(brokers: &str) -> Result<Self, Box<dyn std::error::Error>> {
1376
+ let producer: FutureProducer = ClientConfig::new()
1377
+ .set("bootstrap.servers", brokers)
1378
+ .set("message.timeout.ms", "5000")
1379
+ .set("delivery.timeout.ms", "10000")
1380
+ .set("request.timeout.ms", "5000")
1381
+ .create()?;
1382
+
1383
+ Ok(Self { producer })
1384
+ }
1385
+
1386
+ pub async fn publish_event(&self, topic: &str, event: Event) -> Result<(), Box<dyn std::error::Error>> {
1387
+ let event_json = serde_json::to_vec(&event)?;
1388
+ let key = Some(event.id.as_bytes());
1389
+
1390
+ let record = FutureRecord::to(topic)
1391
+ .key(key)
1392
+ .payload(&event_json)
1393
+ .headers(
1394
+ rdkafka::message::Headers::new()
1395
+ .add("event_type", &event.event_type)
1396
+ .add("version", &event.version.to_string())
1397
+ );
1398
+
1399
+ let delivery_future = self.producer.send(record, Duration::from_secs(0));
1400
+
1401
+ match timeout(Duration::from_secs(5), delivery_future).await {
1402
+ Ok(Ok((partition, offset))) => {
1403
+ tracing::info!(
1404
+ "Event published to partition {} at offset {}",
1405
+ partition,
1406
+ offset
1407
+ );
1408
+ Ok(())
1409
+ }
1410
+ Ok(Err((kafka_error, _))) => {
1411
+ tracing::error!("Failed to publish event: {}", kafka_error);
1412
+ Err(Box::new(kafka_error))
1413
+ }
1414
+ Err(_) => {
1415
+ tracing::error!("Timeout while publishing event");
1416
+ Err("Timeout while publishing event".into())
1417
+ }
1418
+ }
1419
+ }
1420
+ }
1421
+
1422
+ // Event consumer
1423
+ use rdkafka::{
1424
+ config::ConsumerConfig,
1425
+ consumer::{StreamConsumer, Consumer},
1426
+ message::BorrowedMessage,
1427
+ };
1428
+
1429
+ pub struct EventConsumer {
1430
+ consumer: StreamConsumer,
1431
+ }
1432
+
1433
+ impl EventConsumer {
1434
+ pub fn new(brokers: &str, group_id: &str) -> Result<Self, Box<dyn std::error::Error>> {
1435
+ let consumer: StreamConsumer = ClientConfig::new()
1436
+ .set("group.id", group_id)
1437
+ .set("bootstrap.servers", brokers)
1438
+ .set("enable.auto.commit", "false")
1439
+ .set("auto.offset.reset", "earliest")
1440
+ .create()?;
1441
+
1442
+ Ok(Self { consumer })
1443
+ }
1444
+
1445
+ pub async fn subscribe(&self, topics: &[&str]) -> Result<(), Box<dyn std::error::Error>> {
1446
+ self.consumer.subscribe(topics)?;
1447
+ Ok(())
1448
+ }
1449
+
1450
+ pub async fn start_consuming<F, Fut>(&mut self, handler: F)
1451
+ where
1452
+ F: Fn(Event) -> Fut + Send + Sync + 'static,
1453
+ Fut: std::future::Future<Output = Result<(), Box<dyn std::error::Error>>> + Send,
1454
+ {
1455
+ while let Some(message_result = self.consumer.recv().await {
1456
+ match message_result {
1457
+ Ok(message) => {
1458
+ match self.handle_message(&message, &handler).await {
1459
+ Ok(_) => {
1460
+ // Commit message offset
1461
+ let _ = self.consumer.commit_message(&message, rdkafka::consumer::CommitMode::Async).await;
1462
+ }
1463
+ Err(e) => {
1464
+ tracing::error!("Error handling message: {}", e);
1465
+ }
1466
+ }
1467
+ }
1468
+ Err(e) => {
1469
+ tracing::error!("Error receiving message: {}", e);
1470
+ }
1471
+ }
1472
+ }
1473
+ }
1474
+
1475
+ async fn handle_message<F, Fut>(
1476
+ &self,
1477
+ message: &BorrowedMessage<'_>,
1478
+ handler: &F,
1479
+ ) -> Result<(), Box<dyn std::error::Error>>
1480
+ where
1481
+ F: Fn(Event) -> Fut,
1482
+ Fut: std::future::Future<Output = Result<(), Box<dyn std::error::Error>>>,
1483
+ {
1484
+ let payload = message.payload().ok_or("Empty message payload")?;
1485
+
1486
+ let event: Event = serde_json::from_slice(payload)?;
1487
+
1488
+ handler(event).await
1489
+ }
1490
+ }
1491
+ ```
1492
+
1493
+ ## Modern Development Workflow
1494
+
1495
+ ### Configuration Management
1496
+
1497
+ ```rust
1498
+ // src/config/mod.rs
1499
+ use serde::{Deserialize, Serialize};
1500
+ use std::path::Path;
1501
+
1502
+ #[derive(Debug, Clone, Deserialize)]
1503
+ pub struct Config {
1504
+ pub server: ServerConfig,
1505
+ pub database: DatabaseConfig,
1506
+ pub auth: AuthConfig,
1507
+ pub kafka: KafkaConfig,
1508
+ pub logging: LoggingConfig,
1509
+ }
1510
+
1511
+ #[derive(Debug, Clone, Deserialize)]
1512
+ pub struct ServerConfig {
1513
+ pub host: String,
1514
+ pub port: u16,
1515
+ pub workers: usize,
1516
+ }
1517
+
1518
+ #[derive(Debug, Clone, Deserialize)]
1519
+ pub struct DatabaseConfig {
1520
+ pub url: String,
1521
+ pub max_connections: u32,
1522
+ pub min_connections: u32,
1523
+ pub connect_timeout: u64,
1524
+ pub acquire_timeout: u64,
1525
+ }
1526
+
1527
+ #[derive(Debug, Clone, Deserialize)]
1528
+ pub struct AuthConfig {
1529
+ pub jwt_secret: String,
1530
+ pub token_expiry_hours: u64,
1531
+ pub bcrypt_cost: u32,
1532
+ }
1533
+
1534
+ #[derive(Debug, Clone, Deserialize)]
1535
+ pub struct KafkaConfig {
1536
+ pub brokers: Vec<String>,
1537
+ pub group_id: String,
1538
+ pub topic_prefix: String,
1539
+ }
1540
+
1541
+ #[derive(Debug, Clone, Deserialize)]
1542
+ pub struct LoggingConfig {
1543
+ pub level: String,
1544
+ pub format: String,
1545
+ pub output: String,
1546
+ }
1547
+
1548
+ impl Config {
1549
+ pub fn load() -> Result<Self, Box<dyn std::error::Error>> {
1550
+ // Try environment variable first
1551
+ if let Ok(config_path) = std::env::var("CONFIG_PATH") {
1552
+ return Self::load_from_file(&config_path);
1553
+ }
1554
+
1555
+ // Try default locations
1556
+ let default_paths = vec![
1557
+ "config.toml",
1558
+ "config.yaml",
1559
+ "/etc/my-app/config.toml",
1560
+ "/etc/my-app/config.yaml",
1561
+ ];
1562
+
1563
+ for path in default_paths {
1564
+ if Path::new(path).exists() {
1565
+ return Self::load_from_file(path);
1566
+ }
1567
+ }
1568
+
1569
+ // Fallback to environment variables
1570
+ Self::load_from_env()
1571
+ }
1572
+
1573
+ fn load_from_file(path: &str) -> Result<Self, Box<dyn std::error::Error>> {
1574
+ let content = std::fs::read_to_string(path)?;
1575
+
1576
+ if path.ends_with(".toml") {
1577
+ let config: Config = toml::from_str(&content)?;
1578
+ Ok(config)
1579
+ } else if path.ends_with(".yaml") || path.ends_with(".yml") {
1580
+ let config: Config = serde_yaml::from_str(&content)?;
1581
+ Ok(config)
1582
+ } else {
1583
+ Err("Unsupported config file format".into())
1584
+ }
1585
+ }
1586
+
1587
+ fn load_from_env() -> Result<Self, Box<dyn std::error::Error>> {
1588
+ Ok(Config {
1589
+ server: ServerConfig {
1590
+ host: std::env::var("SERVER_HOST").unwrap_or_else(|_| "0.0.0.0".to_string()),
1591
+ port: std::env::var("SERVER_PORT")
1592
+ .unwrap_or_else(|_| "8080".to_string())
1593
+ .parse()?,
1594
+ workers: std::env::var("SERVER_WORKERS")
1595
+ .unwrap_or_else(|_| "4".to_string())
1596
+ .parse()?,
1597
+ },
1598
+ database: DatabaseConfig {
1599
+ url: std::env::var("DATABASE_URL")?,
1600
+ max_connections: std::env::var("DATABASE_MAX_CONNECTIONS")
1601
+ .unwrap_or_else(|_| "10".to_string())
1602
+ .parse()?,
1603
+ min_connections: std::env::var("DATABASE_MIN_CONNECTIONS")
1604
+ .unwrap_or_else(|_| "1".to_string())
1605
+ .parse()?,
1606
+ connect_timeout: std::env::var("DATABASE_CONNECT_TIMEOUT")
1607
+ .unwrap_or_else(|_| "30".to_string())
1608
+ .parse()?,
1609
+ acquire_timeout: std::env::var("DATABASE_ACQUIRE_TIMEOUT")
1610
+ .unwrap_or_else(|_| "30".to_string())
1611
+ .parse()?,
1612
+ },
1613
+ auth: AuthConfig {
1614
+ jwt_secret: std::env::var("JWT_SECRET")?,
1615
+ token_expiry_hours: std::env::var("TOKEN_EXPIRY_HOURS")
1616
+ .unwrap_or_else(|_| "24".to_string())
1617
+ .parse()?,
1618
+ bcrypt_cost: std::env::var("BCRYPT_COST")
1619
+ .unwrap_or_else(|_| "12".to_string())
1620
+ .parse()?,
1621
+ },
1622
+ kafka: KafkaConfig {
1623
+ brokers: std::env::var("KAFKA_BROKERS")
1624
+ .unwrap_or_else(|_| "localhost:9092".to_string())
1625
+ .split(',')
1626
+ .map(|s| s.trim().to_string())
1627
+ .collect(),
1628
+ group_id: std::env::var("KAFKA_GROUP_ID")
1629
+ .unwrap_or_else(|_| "my-app".to_string()),
1630
+ topic_prefix: std::env::var("KAFKA_TOPIC_PREFIX")
1631
+ .unwrap_or_else(|_| "my-app".to_string()),
1632
+ },
1633
+ logging: LoggingConfig {
1634
+ level: std::env::var("LOG_LEVEL").unwrap_or_else(|_| "info".to_string()),
1635
+ format: std::env::var("LOG_FORMAT").unwrap_or_else(|_| "json".to_string()),
1636
+ output: std::env::var("LOG_OUTPUT").unwrap_or_else(|_| "stdout".to_string()),
1637
+ },
1638
+ })
1639
+ }
1640
+ }
1641
+ ```
1642
+
1643
+ ### Cargo Workspace Configuration
1644
+
1645
+ ```toml
1646
+ # Cargo.toml (workspace root)
1647
+ [workspace]
1648
+ members = [
1649
+ "crates/common",
1650
+ "crates/server",
1651
+ "crates/client",
1652
+ "crates/cli",
1653
+ ]
1654
+
1655
+ [workspace.package]
1656
+ version = "0.1.0"
1657
+ edition = "2021"
1658
+ authors = ["Your Name <your.email@example.com>"]
1659
+ license = "MIT OR Apache-2.0"
1660
+ repository = "https://github.com/yourorg/your-project"
1661
+
1662
+ [workspace.dependencies]
1663
+ # Async runtime
1664
+ tokio = { version = "1.42", features = ["full"] }
1665
+ tokio-util = "0.7"
1666
+
1667
+ # Web framework
1668
+ axum = "0.8"
1669
+ tower = "0.5"
1670
+ tower-http = "0.6"
1671
+
1672
+ # Database
1673
+ sqlx = { version = "0.8", features = ["runtime-tokio-rustls", "postgres", "chrono", "uuid"] }
1674
+ diesel = { version = "2.2", features = ["postgres", "uuid", "chrono"] }
1675
+
1676
+ # Serialization
1677
+ serde = { version = "1.0", features = ["derive"] }
1678
+ serde_json = "1.0"
1679
+
1680
+ # Error handling
1681
+ thiserror = "1.0"
1682
+ anyhow = "1.0"
1683
+
1684
+ # Logging
1685
+ tracing = "0.1"
1686
+ tracing-subscriber = { version = "0.3", features = ["json"] }
1687
+
1688
+ # Security
1689
+ argon2 = "0.5"
1690
+ jsonwebtoken = "9.3"
1691
+ uuid = { version = "1.11", features = ["v4", "serde"] }
1692
+
1693
+ # Configuration
1694
+ config = "0.14"
1695
+ serde_yaml = "0.9"
1696
+
1697
+ # Testing
1698
+ tokio-test = "0.4"
1699
+ mockall = "0.13"
1700
+
1701
+ [profile.release]
1702
+ lto = true
1703
+ codegen-units = 1
1704
+ panic = "abort"
1705
+
1706
+ [profile.dev]
1707
+ debug = true
1708
+ ```
1709
+
1710
+ ### GitHub Actions CI/CD
1711
+
1712
+ ```yaml
1713
+ # .github/workflows/ci.yml
1714
+ name: CI
1715
+
1716
+ on:
1717
+ push:
1718
+ branches: [ main, develop ]
1719
+ pull_request:
1720
+ branches: [ main ]
1721
+
1722
+ env:
1723
+ CARGO_TERM_COLOR: always
1724
+
1725
+ jobs:
1726
+ test:
1727
+ name: Test Suite
1728
+ runs-on: ubuntu-latest
1729
+
1730
+ strategy:
1731
+ matrix:
1732
+ rust:
1733
+ - stable
1734
+ - beta
1735
+ - nightly
1736
+ features:
1737
+ - ""
1738
+ - "kafka,database"
1739
+
1740
+ steps:
1741
+ - uses: actions/checkout@v4
1742
+
1743
+ - name: Install Rust
1744
+ uses: dtolnay/rust-toolchain@master
1745
+ with:
1746
+ toolchain: ${{ matrix.rust }}
1747
+ components: rustfmt, clippy
1748
+
1749
+ - name: Cache dependencies
1750
+ uses: actions/cache@v4
1751
+ with:
1752
+ path: |
1753
+ ~/.cargo/registry
1754
+ ~/.cargo/git
1755
+ target
1756
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
1757
+
1758
+ - name: Install system dependencies
1759
+ run: |
1760
+ sudo apt-get update
1761
+ sudo apt-get install -y postgresql-client libpq-dev
1762
+
1763
+ - name: Check formatting
1764
+ run: cargo fmt --all -- --check
1765
+
1766
+ - name: Run clippy
1767
+ run: cargo clippy --all-targets --all-features -- -D warnings
1768
+
1769
+ - name: Run tests
1770
+ run: cargo test --workspace --features ${{ matrix.features }}
1771
+
1772
+ - name: Run doc tests
1773
+ run: cargo test --doc --features ${{ matrix.features }}
1774
+
1775
+ coverage:
1776
+ name: Code Coverage
1777
+ runs-on: ubuntu-latest
1778
+
1779
+ steps:
1780
+ - uses: actions/checkout@v4
1781
+
1782
+ - name: Install Rust
1783
+ uses: dtolnay/rust-toolchain@stable
1784
+ with:
1785
+ components: llvm-tools-preview
1786
+
1787
+ - name: Install cargo-llvm-cov
1788
+ run: cargo install cargo-llvm-cov
1789
+
1790
+ - name: Install system dependencies
1791
+ run: |
1792
+ sudo apt-get update
1793
+ sudo apt-get install -y postgresql-client libpq-dev
1794
+
1795
+ - name: Generate code coverage
1796
+ run: cargo llvm-cov --workspace --lcov --output-path lcov.info
1797
+
1798
+ - name: Upload coverage to Codecov
1799
+ uses: codecov/codecov-action@v4
1800
+ with:
1801
+ files: lcov.info
1802
+ fail_ci_if_error: true
1803
+
1804
+ security:
1805
+ name: Security Audit
1806
+ runs-on: ubuntu-latest
1807
+
1808
+ steps:
1809
+ - uses: actions/checkout@v4
1810
+
1811
+ - name: Install Rust
1812
+ uses: dtolnay/rust-toolchain@stable
1813
+
1814
+ - name: Install cargo-audit
1815
+ run: cargo install cargo-audit
1816
+
1817
+ - name: Security audit
1818
+ run: cargo audit
1819
+
1820
+ - name: Install cargo-deny
1821
+ run: cargo install cargo-deny
1822
+
1823
+ - name: Check dependencies
1824
+ run: cargo deny check
1825
+
1826
+ build:
1827
+ name: Build Release
1828
+ runs-on: ubuntu-latest
1829
+
1830
+ needs: [test, security]
1831
+
1832
+ steps:
1833
+ - uses: actions/checkout@v4
1834
+
1835
+ - name: Install Rust
1836
+ uses: dtolnay/rust-toolchain@stable
1837
+
1838
+ - name: Cache dependencies
1839
+ uses: actions/cache@v4
1840
+ with:
1841
+ path: |
1842
+ ~/.cargo/registry
1843
+ ~/.cargo/git
1844
+ target
1845
+ key: ${{ runner.os }}-cargo-release-${{ hashFiles('**/Cargo.lock') }}
1846
+
1847
+ - name: Build release
1848
+ run: cargo build --workspace --release
1849
+
1850
+ - name: Upload binary artifacts
1851
+ uses: actions/upload-artifact@v4
1852
+ with:
1853
+ name: release-binaries
1854
+ path: target/release/
1855
+ ```
1856
+
1857
+ ---
93
1858
 
94
- - alfred-trust-validation (coverage verification)
95
- - alfred-code-reviewer (Rust-specific review)
96
- - alfred-performance-optimizer (Rust benchmarking)
1859
+ **Created by**: MoAI Language Skill Factory
1860
+ **Last Updated**: 2025-11-06
1861
+ **Version**: 2.0.0
1862
+ **Rust Target**: 1.91+ with latest language features
97
1863
 
98
- ## Best Practices
99
- - Enable automatic validation by matching your linter with the language's official style guide.
100
- - Fix test/build pipelines with reproducible commands in CI.
1864
+ This skill provides comprehensive Rust development guidance with 2025 best practices, covering everything from basic memory safety to advanced systems programming and performance-critical applications.