Skip to content

Commit c46b800

Browse files
steinerkelvinclaude
andcommitted
docs: add guideline to avoid Rust keywords as field names
Added explicit rules to both CLAUDE.md and CONTRIBUTING.md prohibiting the use of Rust keywords (type, use, trait, impl, etc.) as struct field names, especially in public APIs. Problem: Rust keywords require the r# prefix (e.g., r#type), which causes serialization inconsistencies across language bindings: - Polkadot.js converts to r_type or rType - Serde serializes as type - Creates confusion and breaks API consistency Solution: Use alternative names like kind, variant, scope, category, or mode instead. This guideline applies to all public structs, especially those in api crates and types exposed to external clients. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 51e7ea5 commit c46b800

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

CLAUDE.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,19 @@ Torus is a stake-driven peer-to-peer network built on Substrate. The blockchain
2626
The `permission0` pallet manages delegated permissions and access control within the Torus network. Key components:
2727

2828
**Core Permission Types** (`pallets/permission0/src/permission.rs`):
29+
2930
- `PermissionContract<T>` - Main permission structure with delegator, recipient, scope, duration, and enforcement
3031
- `PermissionId` - Unique permission identifier (H256 hash)
3132
- `PermissionScope<T>` - Defines what actions the permission covers
3233
- `NamespaceScope<T>` - Defines namespace path permissions for delegation
3334

3435
**Permission Scopes** (`pallets/permission0/src/permission/`):
36+
3537
- `pallets/permission0/src/permission/curator.rs` - `CuratorPermissions` and `CuratorScope` types
3638
- `pallets/permission0/src/permission/emission.rs` - `EmissionAllocation`, `DistributionControl`, and `EmissionScope` types
3739

3840
**Implementation Handlers** (`pallets/permission0/src/ext/`):
41+
3942
- `pallets/permission0/src/ext/curator_impl.rs` - Functions for curator permission enforcement
4043
- `pallets/permission0/src/ext/emission_impl.rs` - Functions for emission permission enforcement
4144
- `pallets/permission0/src/ext/namespace_impl.rs` - Functions for namespace permission enforcement
@@ -77,6 +80,7 @@ cargo build --release # Build the node
7780
- **MUST ALWAYS** use `ensure!` macro for validation, NEVER `assert!`
7881
- **MUST ALWAYS** use the `?` operator for error propagation
7982
- **MUST ALWAYS** use pattern matching with proper error handling:
83+
8084
```rust
8185
let Some(value) = some_option else {
8286
return Err(Error::<T>::SomeError.into());
@@ -132,17 +136,32 @@ cargo build --release # Build the node
132136
- **MUST ALWAYS** use proper type conversions with `.try_into()` and handle errors
133137
- **MUST NEVER** use `as` for lossy numeric conversions
134138

139+
### API Design - MANDATORY
140+
141+
- **MUST NEVER** use Rust keywords as struct field names (e.g., `type`, `use`, `trait`, `impl`)
142+
- **PROBLEM**: Rust keywords require `r#` prefix (e.g., `r#type`), causing serialization inconsistencies:
143+
- Polkadot.js converts to `r_type` or `rType`
144+
- Serde serializes as `type`
145+
- Creates confusion and breaks API consistency across language bindings
146+
- **MUST ALWAYS** use alternative names: `kind`, `variant`, `scope`, `category`, `mode`, etc.
147+
- **APPLIES TO**: All public structs, especially those in `api` crates and types exposed to external clients
148+
135149
### Common Code Patterns - REQUIRED
136150

137151
- **MUST ALWAYS** emit events after successful state changes:
152+
138153
```rust
139154
Pallet::<T>::deposit_event(Event::<T>::SomethingHappened(who, what));
140155
```
156+
141157
- **MUST ALWAYS** validate string data is UTF-8:
158+
142159
```rust
143160
ensure!(core::str::from_utf8(bytes).is_ok(), Error::<T>::InvalidUtf8);
144161
```
162+
145163
- **MUST ALWAYS** check bounds before operations:
164+
146165
```rust
147166
ensure!(value <= T::MaxValue::get(), Error::<T>::ValueTooLarge);
148167
```
@@ -169,10 +188,10 @@ cargo build --release # Build the node
169188
- **MUST NEVER** use repetitive and redundant comments within code
170189
- **MUST NEVER** ignore compiler or clippy warnings with `#[allow(...)]`
171190

172-
### Before committing:
191+
### Before committing
173192

174193
1. **MUST** run `cargo fmt`
175194
2. **MUST** run `just check` and fix all warnings
176195
3. **MUST** run `just test` and ensure all pass
177196
4. **MUST** run `cargo xtask coverage` to verify coverage
178-
5. **MUST** test runtime upgrades if storage changed
197+
5. **MUST** test runtime upgrades if storage changed

CONTRIBUTING.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ Be idiomatic. Use `Iterator`s, `Result`s, etc. PLEASE. Take a look at [Rust's AP
6767
- the WASM runtime that Substrate runs on cannot unwind, so panics in functions like `on_initialize` will halt the chain (been there - more than once);
6868
- use `Option` and `Result` types properly for error handling. NEVER allow `unused_must_use`. NEVER;
6969
- always prefer panic-free functions and treat all potential errors (`checked_div` in favor of `/`, etc.).
70+
- **Avoid Rust keywords as field names:**
71+
- Never use Rust keywords (`type`, `use`, `trait`, `impl`, etc.) as struct field names, especially in public APIs;
72+
- keywords require the `r#` prefix in Rust (e.g., `r#type`), which causes serialization inconsistencies across language bindings;
73+
- Polkadot.js may convert `r#type` to `r_type` or `rType`, while Serde serializes it as `type`, creating confusion;
74+
- use alternative names like `kind`, `variant`, `scope`, `category`, or `mode` instead.
7075

7176
## Storage modifications and migrations
7277

0 commit comments

Comments
 (0)