oh-my-customcode 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +287 -0
- package/dist/cli/index.js +13299 -0
- package/dist/index.js +927 -0
- package/package.json +74 -0
- package/templates/.claude/contexts/dev.md +20 -0
- package/templates/.claude/contexts/ecomode.md +63 -0
- package/templates/.claude/contexts/index.yaml +41 -0
- package/templates/.claude/contexts/research.md +28 -0
- package/templates/.claude/contexts/review.md +23 -0
- package/templates/.claude/hooks/hooks.json +185 -0
- package/templates/.claude/hooks/hud/index.yaml +27 -0
- package/templates/.claude/hooks/hud/update-status.sh +32 -0
- package/templates/.claude/hooks/index.yaml +46 -0
- package/templates/.claude/hooks/memory-persistence/pre-compact.sh +37 -0
- package/templates/.claude/hooks/memory-persistence/session-end.sh +64 -0
- package/templates/.claude/hooks/memory-persistence/session-start.sh +41 -0
- package/templates/.claude/hooks/strategic-compact/suggest-compact.sh +50 -0
- package/templates/.claude/install-hooks.sh +100 -0
- package/templates/.claude/rules/MAY-optimization.md +93 -0
- package/templates/.claude/rules/MUST-agent-design.md +107 -0
- package/templates/.claude/rules/MUST-agent-identification.md +108 -0
- package/templates/.claude/rules/MUST-continuous-improvement.md +132 -0
- package/templates/.claude/rules/MUST-intent-transparency.md +199 -0
- package/templates/.claude/rules/MUST-language-policy.md +62 -0
- package/templates/.claude/rules/MUST-orchestrator-coordination.md +266 -0
- package/templates/.claude/rules/MUST-parallel-execution.md +341 -0
- package/templates/.claude/rules/MUST-permissions.md +84 -0
- package/templates/.claude/rules/MUST-safety.md +69 -0
- package/templates/.claude/rules/MUST-sync-verification.md +219 -0
- package/templates/.claude/rules/MUST-tool-identification.md +112 -0
- package/templates/.claude/rules/SHOULD-ecomode.md +145 -0
- package/templates/.claude/rules/SHOULD-error-handling.md +102 -0
- package/templates/.claude/rules/SHOULD-hud-statusline.md +89 -0
- package/templates/.claude/rules/SHOULD-interaction.md +103 -0
- package/templates/.claude/rules/SHOULD-memory-integration.md +114 -0
- package/templates/.claude/rules/SHOULD-pipeline-mode.md +165 -0
- package/templates/.claude/rules/index.yaml +125 -0
- package/templates/.claude/uninstall-hooks.sh +52 -0
- package/templates/CLAUDE.md.en +259 -0
- package/templates/CLAUDE.md.ko +259 -0
- package/templates/agents/index.yaml +237 -0
- package/templates/agents/infra-engineer/aws-expert/AGENT.md +47 -0
- package/templates/agents/infra-engineer/aws-expert/index.yaml +27 -0
- package/templates/agents/infra-engineer/docker-expert/AGENT.md +47 -0
- package/templates/agents/infra-engineer/docker-expert/index.yaml +27 -0
- package/templates/agents/manager/creator/AGENT.md +274 -0
- package/templates/agents/manager/creator/index.yaml +66 -0
- package/templates/agents/manager/gitnerd/AGENT.md +91 -0
- package/templates/agents/manager/gitnerd/index.yaml +55 -0
- package/templates/agents/manager/sauron/AGENT.md +153 -0
- package/templates/agents/manager/sauron/index.yaml +52 -0
- package/templates/agents/manager/supplier/AGENT.md +142 -0
- package/templates/agents/manager/supplier/index.yaml +31 -0
- package/templates/agents/manager/sync-checker/AGENT.md +34 -0
- package/templates/agents/manager/sync-checker/index.yaml +32 -0
- package/templates/agents/manager/updater/AGENT.md +125 -0
- package/templates/agents/manager/updater/index.yaml +31 -0
- package/templates/agents/orchestrator/dev-lead/AGENT.md +116 -0
- package/templates/agents/orchestrator/dev-lead/index.yaml +73 -0
- package/templates/agents/orchestrator/planner/AGENT.md +102 -0
- package/templates/agents/orchestrator/planner/index.yaml +38 -0
- package/templates/agents/orchestrator/qa-lead/AGENT.md +92 -0
- package/templates/agents/orchestrator/qa-lead/index.yaml +40 -0
- package/templates/agents/orchestrator/secretary/AGENT.md +132 -0
- package/templates/agents/orchestrator/secretary/index.yaml +55 -0
- package/templates/agents/qa-team/qa-engineer/AGENT.md +98 -0
- package/templates/agents/qa-team/qa-engineer/index.yaml +59 -0
- package/templates/agents/qa-team/qa-planner/AGENT.md +75 -0
- package/templates/agents/qa-team/qa-planner/index.yaml +47 -0
- package/templates/agents/qa-team/qa-writer/AGENT.md +98 -0
- package/templates/agents/qa-team/qa-writer/index.yaml +44 -0
- package/templates/agents/sw-architect/documenter/AGENT.md +120 -0
- package/templates/agents/sw-architect/documenter/index.yaml +39 -0
- package/templates/agents/sw-architect/speckit-agent/AGENT.md +127 -0
- package/templates/agents/sw-architect/speckit-agent/index.yaml +78 -0
- package/templates/agents/sw-engineer/backend/express-expert/AGENT.md +132 -0
- package/templates/agents/sw-engineer/backend/express-expert/index.yaml +36 -0
- package/templates/agents/sw-engineer/backend/fastapi-expert/AGENT.md +47 -0
- package/templates/agents/sw-engineer/backend/fastapi-expert/index.yaml +27 -0
- package/templates/agents/sw-engineer/backend/go-backend-expert/AGENT.md +47 -0
- package/templates/agents/sw-engineer/backend/go-backend-expert/index.yaml +27 -0
- package/templates/agents/sw-engineer/backend/nestjs-expert/AGENT.md +107 -0
- package/templates/agents/sw-engineer/backend/nestjs-expert/index.yaml +43 -0
- package/templates/agents/sw-engineer/backend/springboot-expert/AGENT.md +103 -0
- package/templates/agents/sw-engineer/backend/springboot-expert/index.yaml +69 -0
- package/templates/agents/sw-engineer/frontend/svelte-agent/AGENT.md +71 -0
- package/templates/agents/sw-engineer/frontend/svelte-agent/index.yaml +41 -0
- package/templates/agents/sw-engineer/frontend/vercel-agent/AGENT.md +67 -0
- package/templates/agents/sw-engineer/frontend/vercel-agent/index.yaml +43 -0
- package/templates/agents/sw-engineer/frontend/vuejs-agent/AGENT.md +71 -0
- package/templates/agents/sw-engineer/frontend/vuejs-agent/index.yaml +48 -0
- package/templates/agents/sw-engineer/language/golang-expert/AGENT.md +47 -0
- package/templates/agents/sw-engineer/language/golang-expert/index.yaml +27 -0
- package/templates/agents/sw-engineer/language/java21-expert/AGENT.md +122 -0
- package/templates/agents/sw-engineer/language/java21-expert/index.yaml +51 -0
- package/templates/agents/sw-engineer/language/kotlin-expert/AGENT.md +47 -0
- package/templates/agents/sw-engineer/language/kotlin-expert/index.yaml +27 -0
- package/templates/agents/sw-engineer/language/python-expert/AGENT.md +47 -0
- package/templates/agents/sw-engineer/language/python-expert/index.yaml +27 -0
- package/templates/agents/sw-engineer/language/rust-expert/AGENT.md +47 -0
- package/templates/agents/sw-engineer/language/rust-expert/index.yaml +27 -0
- package/templates/agents/sw-engineer/language/typescript-expert/AGENT.md +47 -0
- package/templates/agents/sw-engineer/language/typescript-expert/index.yaml +27 -0
- package/templates/agents/sw-engineer/tooling/bun-expert/AGENT.md +73 -0
- package/templates/agents/sw-engineer/tooling/bun-expert/index.yaml +46 -0
- package/templates/agents/sw-engineer/tooling/npm-expert/AGENT.md +160 -0
- package/templates/agents/sw-engineer/tooling/npm-expert/index.yaml +45 -0
- package/templates/agents/sw-engineer/tooling/optimizer/AGENT.md +170 -0
- package/templates/agents/sw-engineer/tooling/optimizer/index.yaml +45 -0
- package/templates/agents/system/memory-keeper/AGENT.md +126 -0
- package/templates/agents/system/memory-keeper/index.yaml +45 -0
- package/templates/agents/system/naggy/AGENT.md +72 -0
- package/templates/agents/system/naggy/index.yaml +35 -0
- package/templates/commands/COMMANDS.md +136 -0
- package/templates/commands/creator/agent.md +121 -0
- package/templates/commands/dev/refactor.md +126 -0
- package/templates/commands/dev/review.md +82 -0
- package/templates/commands/git/branch.yaml +8 -0
- package/templates/commands/git/commit.yaml +4 -0
- package/templates/commands/git/pr.yaml +4 -0
- package/templates/commands/git/status.yaml +4 -0
- package/templates/commands/git/sync.yaml +4 -0
- package/templates/commands/index.yaml +225 -0
- package/templates/commands/intent/explain.md +144 -0
- package/templates/commands/memory/recall.md +164 -0
- package/templates/commands/memory/save.md +128 -0
- package/templates/commands/naggy/add.yaml +8 -0
- package/templates/commands/naggy/done.yaml +8 -0
- package/templates/commands/naggy/list.yaml +4 -0
- package/templates/commands/naggy/priority.yaml +11 -0
- package/templates/commands/naggy/remind.yaml +4 -0
- package/templates/commands/npm/audit.yaml +62 -0
- package/templates/commands/npm/publish.yaml +52 -0
- package/templates/commands/npm/version.yaml +62 -0
- package/templates/commands/optimize/analyze.yaml +34 -0
- package/templates/commands/optimize/bundle.yaml +50 -0
- package/templates/commands/optimize/report.yaml +56 -0
- package/templates/commands/pipeline/list.md +81 -0
- package/templates/commands/pipeline/run.md +127 -0
- package/templates/commands/sauron/quick.yaml +4 -0
- package/templates/commands/sauron/report.yaml +4 -0
- package/templates/commands/sauron/watch.yaml +4 -0
- package/templates/commands/supplier/audit.md +133 -0
- package/templates/commands/supplier/fix.md +121 -0
- package/templates/commands/sync/agents.yaml +4 -0
- package/templates/commands/sync/check.yaml +4 -0
- package/templates/commands/sync/commands.yaml +4 -0
- package/templates/commands/sync/docs.yaml +4 -0
- package/templates/commands/sync/fix.yaml +4 -0
- package/templates/commands/system/help.md +137 -0
- package/templates/commands/system/lists.md +86 -0
- package/templates/commands/system/status.md +163 -0
- package/templates/commands/updater/docs.md +165 -0
- package/templates/commands/updater/external.md +214 -0
- package/templates/guides/aws/common-patterns.md +169 -0
- package/templates/guides/aws/index.yaml +26 -0
- package/templates/guides/aws/well-architected.md +143 -0
- package/templates/guides/claude-code/01-overview.md +42 -0
- package/templates/guides/claude-code/03-tools.md +107 -0
- package/templates/guides/claude-code/04-agent-skills.md +90 -0
- package/templates/guides/claude-code/05-agent-sdk.md +129 -0
- package/templates/guides/claude-code/06-mcp.md +165 -0
- package/templates/guides/claude-code/07-prompt-engineering.md +100 -0
- package/templates/guides/claude-code/08-testing.md +58 -0
- package/templates/guides/claude-code/09-guardrails.md +80 -0
- package/templates/guides/claude-code/10-monitoring.md +89 -0
- package/templates/guides/claude-code/index.yaml +51 -0
- package/templates/guides/docker/compose-best-practices.md +284 -0
- package/templates/guides/docker/dockerfile-best-practices.md +262 -0
- package/templates/guides/docker/index.yaml +26 -0
- package/templates/guides/fastapi/best-practices.md +232 -0
- package/templates/guides/fastapi/index.yaml +21 -0
- package/templates/guides/go-backend/index.yaml +26 -0
- package/templates/guides/go-backend/project-layout.md +243 -0
- package/templates/guides/go-backend/uber-style.md +212 -0
- package/templates/guides/golang/concurrency.md +282 -0
- package/templates/guides/golang/effective-go.md +309 -0
- package/templates/guides/golang/error-handling.md +250 -0
- package/templates/guides/golang/index.yaml +27 -0
- package/templates/guides/index.yaml +101 -0
- package/templates/guides/kotlin/coding-conventions.md +247 -0
- package/templates/guides/kotlin/idioms.md +234 -0
- package/templates/guides/kotlin/index.yaml +26 -0
- package/templates/guides/python/index.yaml +26 -0
- package/templates/guides/python/pep8-style-guide.md +202 -0
- package/templates/guides/python/zen-of-python.md +79 -0
- package/templates/guides/rust/error-handling.md +262 -0
- package/templates/guides/rust/index.yaml +26 -0
- package/templates/guides/rust/ownership.md +180 -0
- package/templates/guides/springboot/best-practices.md +361 -0
- package/templates/guides/springboot/index.yaml +22 -0
- package/templates/guides/typescript/advanced-types.md +225 -0
- package/templates/guides/typescript/index.yaml +26 -0
- package/templates/guides/typescript/type-system.md +219 -0
- package/templates/guides/web-design/accessibility.md +66 -0
- package/templates/guides/web-design/index.yaml +20 -0
- package/templates/guides/web-design/performance.md +102 -0
- package/templates/pipelines/examples/code-review.yaml +66 -0
- package/templates/pipelines/index.yaml +18 -0
- package/templates/pipelines/templates/pipeline-template.yaml +50 -0
- package/templates/skills/backend/fastapi-best-practices/SKILL.md +269 -0
- package/templates/skills/backend/fastapi-best-practices/index.yaml +25 -0
- package/templates/skills/backend/go-backend-best-practices/SKILL.md +337 -0
- package/templates/skills/backend/go-backend-best-practices/index.yaml +26 -0
- package/templates/skills/backend/springboot-best-practices/SKILL.md +356 -0
- package/templates/skills/backend/springboot-best-practices/index.yaml +27 -0
- package/templates/skills/development/go-best-practices/SKILL.md +202 -0
- package/templates/skills/development/go-best-practices/index.yaml +25 -0
- package/templates/skills/development/kotlin-best-practices/SKILL.md +255 -0
- package/templates/skills/development/kotlin-best-practices/index.yaml +27 -0
- package/templates/skills/development/python-best-practices/SKILL.md +221 -0
- package/templates/skills/development/python-best-practices/index.yaml +25 -0
- package/templates/skills/development/react-best-practices/SKILL.md +100 -0
- package/templates/skills/development/react-best-practices/index.yaml +39 -0
- package/templates/skills/development/rust-best-practices/SKILL.md +266 -0
- package/templates/skills/development/rust-best-practices/index.yaml +26 -0
- package/templates/skills/development/typescript-best-practices/SKILL.md +320 -0
- package/templates/skills/development/typescript-best-practices/index.yaml +28 -0
- package/templates/skills/development/vercel-deploy/SKILL.md +73 -0
- package/templates/skills/development/vercel-deploy/index.yaml +30 -0
- package/templates/skills/development/web-design-guidelines/SKILL.md +117 -0
- package/templates/skills/development/web-design-guidelines/index.yaml +34 -0
- package/templates/skills/index.yaml +129 -0
- package/templates/skills/infrastructure/aws-best-practices/SKILL.md +279 -0
- package/templates/skills/infrastructure/aws-best-practices/index.yaml +27 -0
- package/templates/skills/infrastructure/docker-best-practices/SKILL.md +274 -0
- package/templates/skills/infrastructure/docker-best-practices/index.yaml +26 -0
- package/templates/skills/orchestration/intent-detection/SKILL.md +214 -0
- package/templates/skills/orchestration/intent-detection/index.yaml +30 -0
- package/templates/skills/orchestration/intent-detection/patterns/agent-triggers.yaml +333 -0
- package/templates/skills/orchestration/pipeline-execution/SKILL.md +188 -0
- package/templates/skills/orchestration/pipeline-execution/index.yaml +27 -0
- package/templates/skills/system/memory-management/SKILL.md +194 -0
- package/templates/skills/system/memory-management/index.yaml +30 -0
- package/templates/skills/system/result-aggregation/SKILL.md +163 -0
- package/templates/skills/system/result-aggregation/index.yaml +36 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# The Zen of Python (PEP 20)
|
|
2
|
+
|
|
3
|
+
> Source: https://peps.python.org/pep-0020/
|
|
4
|
+
|
|
5
|
+
Long time Pythoneer Tim Peters succinctly channels the BDFL's guiding principles for Python's design into 20 aphorisms, only 19 of which have been written down.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
>>> import this
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## The 19 Aphorisms
|
|
12
|
+
|
|
13
|
+
1. **Beautiful is better than ugly.**
|
|
14
|
+
- Write elegant, readable code
|
|
15
|
+
|
|
16
|
+
2. **Explicit is better than implicit.**
|
|
17
|
+
- Don't hide behavior; make intentions clear
|
|
18
|
+
|
|
19
|
+
3. **Simple is better than complex.**
|
|
20
|
+
- Choose straightforward solutions
|
|
21
|
+
|
|
22
|
+
4. **Complex is better than complicated.**
|
|
23
|
+
- When complexity is needed, keep it manageable
|
|
24
|
+
|
|
25
|
+
5. **Flat is better than nested.**
|
|
26
|
+
- Avoid deep nesting; keep structures flat
|
|
27
|
+
|
|
28
|
+
6. **Sparse is better than dense.**
|
|
29
|
+
- Don't pack too much into one line
|
|
30
|
+
|
|
31
|
+
7. **Readability counts.**
|
|
32
|
+
- Code is read more often than written
|
|
33
|
+
|
|
34
|
+
8. **Special cases aren't special enough to break the rules.**
|
|
35
|
+
- Consistency matters
|
|
36
|
+
|
|
37
|
+
9. **Although practicality beats purity.**
|
|
38
|
+
- Be pragmatic when needed
|
|
39
|
+
|
|
40
|
+
10. **Errors should never pass silently.**
|
|
41
|
+
- Handle or propagate errors explicitly
|
|
42
|
+
|
|
43
|
+
11. **Unless explicitly silenced.**
|
|
44
|
+
- Intentional suppression is acceptable
|
|
45
|
+
|
|
46
|
+
12. **In the face of ambiguity, refuse the temptation to guess.**
|
|
47
|
+
- Ask for clarification; don't assume
|
|
48
|
+
|
|
49
|
+
13. **There should be one-- and preferably only one --obvious way to do it.**
|
|
50
|
+
- Python favors one canonical approach
|
|
51
|
+
|
|
52
|
+
14. **Although that way may not be obvious at first unless you're Dutch.**
|
|
53
|
+
- (A nod to Guido van Rossum)
|
|
54
|
+
|
|
55
|
+
15. **Now is better than never.**
|
|
56
|
+
- Don't over-plan; start implementing
|
|
57
|
+
|
|
58
|
+
16. **Although never is often better than *right* now.**
|
|
59
|
+
- But don't rush without thought
|
|
60
|
+
|
|
61
|
+
17. **If the implementation is hard to explain, it's a bad idea.**
|
|
62
|
+
- Complexity is a warning sign
|
|
63
|
+
|
|
64
|
+
18. **If the implementation is easy to explain, it may be a good idea.**
|
|
65
|
+
- Simplicity suggests good design
|
|
66
|
+
|
|
67
|
+
19. **Namespaces are one honking great idea -- let's do more of those!**
|
|
68
|
+
- Organize code into clear namespaces
|
|
69
|
+
|
|
70
|
+
## Application
|
|
71
|
+
|
|
72
|
+
When writing Python code, ask yourself:
|
|
73
|
+
- Is this beautiful or ugly?
|
|
74
|
+
- Is this explicit or implicit?
|
|
75
|
+
- Is this simple or complex?
|
|
76
|
+
- Is this readable?
|
|
77
|
+
- Could I easily explain this to someone else?
|
|
78
|
+
|
|
79
|
+
The Zen of Python is not just style guidance—it's a philosophy for writing maintainable, understandable code.
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# Rust Error Handling
|
|
2
|
+
|
|
3
|
+
> Reference for error handling patterns in Rust
|
|
4
|
+
|
|
5
|
+
## Result Type
|
|
6
|
+
|
|
7
|
+
```rust
|
|
8
|
+
enum Result<T, E> {
|
|
9
|
+
Ok(T),
|
|
10
|
+
Err(E),
|
|
11
|
+
}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Basic Usage
|
|
15
|
+
|
|
16
|
+
```rust
|
|
17
|
+
use std::fs::File;
|
|
18
|
+
|
|
19
|
+
fn main() {
|
|
20
|
+
let f = File::open("hello.txt");
|
|
21
|
+
|
|
22
|
+
let f = match f {
|
|
23
|
+
Ok(file) => file,
|
|
24
|
+
Err(error) => panic!("Problem opening file: {:?}", error),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Matching Different Errors
|
|
30
|
+
|
|
31
|
+
```rust
|
|
32
|
+
use std::fs::File;
|
|
33
|
+
use std::io::ErrorKind;
|
|
34
|
+
|
|
35
|
+
fn main() {
|
|
36
|
+
let f = File::open("hello.txt");
|
|
37
|
+
|
|
38
|
+
let f = match f {
|
|
39
|
+
Ok(file) => file,
|
|
40
|
+
Err(error) => match error.kind() {
|
|
41
|
+
ErrorKind::NotFound => match File::create("hello.txt") {
|
|
42
|
+
Ok(fc) => fc,
|
|
43
|
+
Err(e) => panic!("Problem creating file: {:?}", e),
|
|
44
|
+
},
|
|
45
|
+
other_error => panic!("Problem opening file: {:?}", other_error),
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Shortcuts
|
|
52
|
+
|
|
53
|
+
```rust
|
|
54
|
+
// unwrap: panics on error
|
|
55
|
+
let f = File::open("hello.txt").unwrap();
|
|
56
|
+
|
|
57
|
+
// expect: panics with custom message
|
|
58
|
+
let f = File::open("hello.txt").expect("Failed to open hello.txt");
|
|
59
|
+
|
|
60
|
+
// unwrap_or: provides default value
|
|
61
|
+
let f = File::open("hello.txt").unwrap_or(default_file);
|
|
62
|
+
|
|
63
|
+
// unwrap_or_else: computes default on error
|
|
64
|
+
let f = File::open("hello.txt").unwrap_or_else(|error| {
|
|
65
|
+
panic!("Problem opening file: {:?}", error)
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Propagating Errors
|
|
70
|
+
|
|
71
|
+
### With match
|
|
72
|
+
|
|
73
|
+
```rust
|
|
74
|
+
use std::fs::File;
|
|
75
|
+
use std::io::{self, Read};
|
|
76
|
+
|
|
77
|
+
fn read_username() -> Result<String, io::Error> {
|
|
78
|
+
let f = File::open("hello.txt");
|
|
79
|
+
|
|
80
|
+
let mut f = match f {
|
|
81
|
+
Ok(file) => file,
|
|
82
|
+
Err(e) => return Err(e),
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
let mut s = String::new();
|
|
86
|
+
|
|
87
|
+
match f.read_to_string(&mut s) {
|
|
88
|
+
Ok(_) => Ok(s),
|
|
89
|
+
Err(e) => Err(e),
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### With ? Operator
|
|
95
|
+
|
|
96
|
+
```rust
|
|
97
|
+
use std::fs::File;
|
|
98
|
+
use std::io::{self, Read};
|
|
99
|
+
|
|
100
|
+
fn read_username() -> Result<String, io::Error> {
|
|
101
|
+
let mut f = File::open("hello.txt")?;
|
|
102
|
+
let mut s = String::new();
|
|
103
|
+
f.read_to_string(&mut s)?;
|
|
104
|
+
Ok(s)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Chained version
|
|
108
|
+
fn read_username_chained() -> Result<String, io::Error> {
|
|
109
|
+
let mut s = String::new();
|
|
110
|
+
File::open("hello.txt")?.read_to_string(&mut s)?;
|
|
111
|
+
Ok(s)
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Custom Error Types
|
|
116
|
+
|
|
117
|
+
### Simple Custom Error
|
|
118
|
+
|
|
119
|
+
```rust
|
|
120
|
+
use std::fmt;
|
|
121
|
+
|
|
122
|
+
#[derive(Debug)]
|
|
123
|
+
struct MyError {
|
|
124
|
+
message: String,
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
impl fmt::Display for MyError {
|
|
128
|
+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
129
|
+
write!(f, "{}", self.message)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
impl std::error::Error for MyError {}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Error Enum
|
|
137
|
+
|
|
138
|
+
```rust
|
|
139
|
+
use std::io;
|
|
140
|
+
use std::num::ParseIntError;
|
|
141
|
+
|
|
142
|
+
#[derive(Debug)]
|
|
143
|
+
enum AppError {
|
|
144
|
+
Io(io::Error),
|
|
145
|
+
Parse(ParseIntError),
|
|
146
|
+
Custom(String),
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
impl fmt::Display for AppError {
|
|
150
|
+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
151
|
+
match self {
|
|
152
|
+
AppError::Io(e) => write!(f, "IO error: {}", e),
|
|
153
|
+
AppError::Parse(e) => write!(f, "Parse error: {}", e),
|
|
154
|
+
AppError::Custom(msg) => write!(f, "{}", msg),
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
impl std::error::Error for AppError {}
|
|
160
|
+
|
|
161
|
+
impl From<io::Error> for AppError {
|
|
162
|
+
fn from(error: io::Error) -> Self {
|
|
163
|
+
AppError::Io(error)
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
impl From<ParseIntError> for AppError {
|
|
168
|
+
fn from(error: ParseIntError) -> Self {
|
|
169
|
+
AppError::Parse(error)
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Option Type
|
|
175
|
+
|
|
176
|
+
```rust
|
|
177
|
+
enum Option<T> {
|
|
178
|
+
Some(T),
|
|
179
|
+
None,
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Usage
|
|
184
|
+
|
|
185
|
+
```rust
|
|
186
|
+
fn divide(a: f64, b: f64) -> Option<f64> {
|
|
187
|
+
if b == 0.0 {
|
|
188
|
+
None
|
|
189
|
+
} else {
|
|
190
|
+
Some(a / b)
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Pattern matching
|
|
195
|
+
match divide(10.0, 2.0) {
|
|
196
|
+
Some(result) => println!("Result: {}", result),
|
|
197
|
+
None => println!("Cannot divide by zero"),
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Combinators
|
|
201
|
+
let result = divide(10.0, 2.0)
|
|
202
|
+
.map(|x| x * 2.0)
|
|
203
|
+
.unwrap_or(0.0);
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Panic
|
|
207
|
+
|
|
208
|
+
### When to Panic
|
|
209
|
+
|
|
210
|
+
```rust
|
|
211
|
+
// Unrecoverable errors
|
|
212
|
+
panic!("crash and burn");
|
|
213
|
+
|
|
214
|
+
// Assertion failures
|
|
215
|
+
assert!(x > 0, "x must be positive");
|
|
216
|
+
assert_eq!(a, b, "values must be equal");
|
|
217
|
+
|
|
218
|
+
// Unreachable code
|
|
219
|
+
unreachable!("this should never happen");
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Panic vs Result
|
|
223
|
+
|
|
224
|
+
- Use `Result` for recoverable errors
|
|
225
|
+
- Use `panic!` for unrecoverable errors
|
|
226
|
+
- Library code should return `Result`
|
|
227
|
+
- `main` can panic or return `Result`
|
|
228
|
+
|
|
229
|
+
## Best Practices
|
|
230
|
+
|
|
231
|
+
```rust
|
|
232
|
+
// 1. Use ? for propagation
|
|
233
|
+
fn process() -> Result<Data, Error> {
|
|
234
|
+
let input = read_input()?;
|
|
235
|
+
let parsed = parse(input)?;
|
|
236
|
+
Ok(transform(parsed))
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// 2. Add context with map_err
|
|
240
|
+
let file = File::open(&path)
|
|
241
|
+
.map_err(|e| format!("Failed to open {}: {}", path, e))?;
|
|
242
|
+
|
|
243
|
+
// 3. Use anyhow for applications
|
|
244
|
+
use anyhow::{Context, Result};
|
|
245
|
+
|
|
246
|
+
fn main() -> Result<()> {
|
|
247
|
+
let config = read_config()
|
|
248
|
+
.context("Failed to read configuration")?;
|
|
249
|
+
Ok(())
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// 4. Use thiserror for libraries
|
|
253
|
+
use thiserror::Error;
|
|
254
|
+
|
|
255
|
+
#[derive(Error, Debug)]
|
|
256
|
+
pub enum DataError {
|
|
257
|
+
#[error("Invalid input: {0}")]
|
|
258
|
+
InvalidInput(String),
|
|
259
|
+
#[error("IO error")]
|
|
260
|
+
Io(#[from] std::io::Error),
|
|
261
|
+
}
|
|
262
|
+
```
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Rust Guide
|
|
2
|
+
|
|
3
|
+
metadata:
|
|
4
|
+
name: rust
|
|
5
|
+
description: Rust language reference documentation
|
|
6
|
+
|
|
7
|
+
source:
|
|
8
|
+
type: external
|
|
9
|
+
origin: rust-lang.org
|
|
10
|
+
urls:
|
|
11
|
+
- https://doc.rust-lang.org/book/
|
|
12
|
+
- https://rust-lang.github.io/api-guidelines/
|
|
13
|
+
- https://doc.rust-lang.org/nightly/style-guide/
|
|
14
|
+
last_fetched: "2026-01-22"
|
|
15
|
+
|
|
16
|
+
documents:
|
|
17
|
+
- name: ownership
|
|
18
|
+
path: ./ownership.md
|
|
19
|
+
description: Ownership, borrowing, and lifetimes
|
|
20
|
+
|
|
21
|
+
- name: error-handling
|
|
22
|
+
path: ./error-handling.md
|
|
23
|
+
description: Error handling patterns in Rust
|
|
24
|
+
|
|
25
|
+
used_by:
|
|
26
|
+
- rust-expert
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Rust Ownership
|
|
2
|
+
|
|
3
|
+
> Reference for ownership, borrowing, and lifetimes
|
|
4
|
+
|
|
5
|
+
## Ownership Rules
|
|
6
|
+
|
|
7
|
+
1. Each value has exactly one owner
|
|
8
|
+
2. When the owner goes out of scope, the value is dropped
|
|
9
|
+
3. Values can be moved or borrowed
|
|
10
|
+
|
|
11
|
+
## Move Semantics
|
|
12
|
+
|
|
13
|
+
```rust
|
|
14
|
+
// Move ownership
|
|
15
|
+
let s1 = String::from("hello");
|
|
16
|
+
let s2 = s1; // s1 is moved to s2
|
|
17
|
+
// s1 is no longer valid
|
|
18
|
+
|
|
19
|
+
// Clone to copy
|
|
20
|
+
let s1 = String::from("hello");
|
|
21
|
+
let s2 = s1.clone(); // s1 is still valid
|
|
22
|
+
|
|
23
|
+
// Copy types (stack-only data)
|
|
24
|
+
let x = 5;
|
|
25
|
+
let y = x; // x is still valid (i32 implements Copy)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Borrowing
|
|
29
|
+
|
|
30
|
+
### Immutable References
|
|
31
|
+
|
|
32
|
+
```rust
|
|
33
|
+
fn main() {
|
|
34
|
+
let s1 = String::from("hello");
|
|
35
|
+
let len = calculate_length(&s1); // borrow s1
|
|
36
|
+
println!("The length of '{}' is {}.", s1, len);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
fn calculate_length(s: &String) -> usize {
|
|
40
|
+
s.len()
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Mutable References
|
|
45
|
+
|
|
46
|
+
```rust
|
|
47
|
+
fn main() {
|
|
48
|
+
let mut s = String::from("hello");
|
|
49
|
+
change(&mut s);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
fn change(some_string: &mut String) {
|
|
53
|
+
some_string.push_str(", world");
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Borrowing Rules
|
|
58
|
+
|
|
59
|
+
```rust
|
|
60
|
+
// Rule 1: At any time, either ONE mutable reference
|
|
61
|
+
// OR any number of immutable references
|
|
62
|
+
let mut s = String::from("hello");
|
|
63
|
+
|
|
64
|
+
let r1 = &s; // OK
|
|
65
|
+
let r2 = &s; // OK
|
|
66
|
+
// let r3 = &mut s; // ERROR: cannot borrow as mutable
|
|
67
|
+
|
|
68
|
+
let r3 = &mut s; // OK after r1 and r2 are done
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Lifetimes
|
|
72
|
+
|
|
73
|
+
### Basic Syntax
|
|
74
|
+
|
|
75
|
+
```rust
|
|
76
|
+
// Lifetime annotation
|
|
77
|
+
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
|
|
78
|
+
if x.len() > y.len() {
|
|
79
|
+
x
|
|
80
|
+
} else {
|
|
81
|
+
y
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Struct Lifetimes
|
|
87
|
+
|
|
88
|
+
```rust
|
|
89
|
+
struct ImportantExcerpt<'a> {
|
|
90
|
+
part: &'a str,
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
impl<'a> ImportantExcerpt<'a> {
|
|
94
|
+
fn level(&self) -> i32 {
|
|
95
|
+
3
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
fn announce_and_return_part(&self, announcement: &str) -> &str {
|
|
99
|
+
println!("Attention please: {}", announcement);
|
|
100
|
+
self.part
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Lifetime Elision
|
|
106
|
+
|
|
107
|
+
```rust
|
|
108
|
+
// These are equivalent:
|
|
109
|
+
fn first_word(s: &str) -> &str { ... }
|
|
110
|
+
fn first_word<'a>(s: &'a str) -> &'a str { ... }
|
|
111
|
+
|
|
112
|
+
// Elision rules:
|
|
113
|
+
// 1. Each reference parameter gets its own lifetime
|
|
114
|
+
// 2. If exactly one input lifetime, it's assigned to all outputs
|
|
115
|
+
// 3. If &self or &mut self, its lifetime is assigned to outputs
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Static Lifetime
|
|
119
|
+
|
|
120
|
+
```rust
|
|
121
|
+
// 'static: lives for entire program duration
|
|
122
|
+
let s: &'static str = "I have a static lifetime.";
|
|
123
|
+
|
|
124
|
+
// All string literals have 'static lifetime
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Common Patterns
|
|
128
|
+
|
|
129
|
+
### Returning References
|
|
130
|
+
|
|
131
|
+
```rust
|
|
132
|
+
// Cannot return reference to local variable
|
|
133
|
+
fn dangle() -> &String { // ERROR
|
|
134
|
+
let s = String::from("hello");
|
|
135
|
+
&s // s goes out of scope!
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Return owned value instead
|
|
139
|
+
fn no_dangle() -> String {
|
|
140
|
+
let s = String::from("hello");
|
|
141
|
+
s
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Struct with References
|
|
146
|
+
|
|
147
|
+
```rust
|
|
148
|
+
// Struct holding reference must have lifetime
|
|
149
|
+
struct Config<'a> {
|
|
150
|
+
query: &'a str,
|
|
151
|
+
filename: &'a str,
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Implementation with lifetime
|
|
155
|
+
impl<'a> Config<'a> {
|
|
156
|
+
fn new(args: &'a [String]) -> Config<'a> {
|
|
157
|
+
Config {
|
|
158
|
+
query: &args[1],
|
|
159
|
+
filename: &args[2],
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Multiple Lifetimes
|
|
166
|
+
|
|
167
|
+
```rust
|
|
168
|
+
fn longest_with_announcement<'a, 'b>(
|
|
169
|
+
x: &'a str,
|
|
170
|
+
y: &'a str,
|
|
171
|
+
ann: &'b str,
|
|
172
|
+
) -> &'a str {
|
|
173
|
+
println!("Announcement: {}", ann);
|
|
174
|
+
if x.len() > y.len() {
|
|
175
|
+
x
|
|
176
|
+
} else {
|
|
177
|
+
y
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|