A better Rust ATProto crate
1# CLAUDE.md
2
3This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
5## Project Overview
6
7Jacquard is a suite of Rust crates for the AT Protocol (atproto/Bluesky). The project emphasizes spec-compliant, validated, performant baseline types with minimal boilerplate. Key design goals:
8
9- Validated AT Protocol types including typed at:// URIs
10- Custom lexicon extension support
11- Lexicon `Value` type for working with unknown atproto data (dag-cbor or json)
12- Using as much or as little of the crates as needed
13
14## Workspace Structure
15
16This is a Cargo workspace with several crates:
17
18- **jacquard-common**: Core AT Protocol types (DIDs, handles, at-URIs, NSIDs, TIDs, CIDs, etc.) and the `CowStr` type for efficient string handling
19- **jacquard-lexicon**: Lexicon parsing and Rust code generation from lexicon schemas
20- **jacquard-api**: Generated API bindings (currently empty/in development)
21- **jacquard-derive**: Derive macros for lexicon structures
22- **jacquard**: Main binary (currently minimal)
23
24## Development Commands
25
26### Using Nix (preferred)
27```bash
28# Enter dev shell
29nix develop
30
31# Build
32nix build
33
34# Run
35nix develop -c cargo run
36```
37
38### Using Cargo/Just
39```bash
40# Build
41cargo build
42
43# Run tests
44cargo test
45
46# Run specific test
47cargo test <test_name>
48
49# Run specific package tests
50cargo test -p <package_name>
51
52# Run
53cargo run
54
55# Auto-recompile and run
56just watch [ARGS]
57
58# Format and lint all
59just pre-commit-all
60```
61
62## String Type Pattern
63
64The codebase uses a consistent pattern for validated string types. Each type should have:
65
66### Constructors
67- `new()`: Construct from a string slice with appropriate lifetime (borrows)
68- `new_owned()`: Construct from `impl AsRef<str>`, taking ownership
69- `new_static()`: Construct from `&'static str` using `SmolStr`/`CowStr`'s static constructor (no allocation)
70- `raw()`: Same as `new()` but panics instead of returning `Result`
71- `unchecked()`: Same as `new()` but doesn't validate (marked `unsafe`)
72- `as_str()`: Return string slice
73
74### Traits
75All string types should implement:
76- `Serialize` + `Deserialize` (custom impl for latter, sometimes for former)
77- `FromStr`, `Display`
78- `Debug`, `PartialEq`, `Eq`, `Hash`, `Clone`
79- `From<T> for String`, `CowStr`, `SmolStr`
80- `From<String>`, `From<CowStr>`, `From<SmolStr>`, or `TryFrom` if likely to fail
81- `AsRef<str>`
82- `Deref` with `Target = str` (usually)
83
84### Implementation Details
85- Use `#[repr(transparent)]` when possible (exception: at-uri type and components)
86- Use `SmolStr` directly as inner type if most instances will be under 24 bytes
87- Use `CowStr` for longer strings to allow borrowing from input
88- Implement `IntoStatic` trait to take ownership of string types
89
90## Code Style
91
92- Avoid comments for self-documenting code
93- Comments should not detail fixes when refactoring
94- Professional writing within source code and comments only
95- Prioritize long-term maintainability over implementation speed
96
97## Testing
98
99- Write test cases for all critical code
100- Tests can be run per-package or workspace-wide
101- Use `cargo test <name>` to run specific tests
102- Current test coverage: 89 tests in jacquard-common
103
104## Current State & Next Steps
105
106### Completed
107- ✅ Comprehensive validation tests for all core string types (handle, DID, NSID, TID, record key, AT-URI, datetime, language, identifier)
108- ✅ Validated implementations against AT Protocol specs and TypeScript reference implementation
109- ✅ String type interface standardization (Language now has `new_static()`, Datetime has full conversion traits)
110- ✅ Data serialization: Full serialize/deserialize for `Data<'_>`, `Array`, `Object` with format-specific handling (JSON vs CBOR)
111- ✅ CidLink wrapper type with automatic `{"$link": "cid"}` serialization in JSON
112- ✅ Integration test with real Bluesky thread data validates round-trip correctness
113
114### Next Steps
1151. **Lexicon Code Generation**: Begin work on lexicon-to-Rust code generation now that core types are stable