|
| 1 | +# Schema System Implementation Plan |
| 2 | + |
| 3 | +## ✅ STATUS: COMPLETED |
| 4 | + |
| 5 | +**All implementation steps have been successfully completed. The schema system is fully functional with 33 passing tests.** |
| 6 | + |
| 7 | +## Overview |
| 8 | + |
| 9 | +Implemented a complete schema system for zerv that supports: |
| 10 | + |
| 11 | +1. **RON Schema Parsing**: Parse custom schemas from RON (Rust Object Notation) strings ✅ |
| 12 | +2. **Preset Schemas**: Built-in schemas for common versioning patterns ✅ |
| 13 | +3. **Tier-Aware Logic**: Different schema components based on Git state (tagged/distance/dirty) ✅ |
| 14 | +4. **Core Integration**: Bridge `ZervVars` to `Zerv` objects via `create_zerv_version` function ✅ |
| 15 | + |
| 16 | +## Architecture |
| 17 | + |
| 18 | +``` |
| 19 | +ZervVars → create_zerv_version() → Zerv |
| 20 | + ↓ |
| 21 | + Schema Selection Logic: |
| 22 | + - schema_name → Preset Schema |
| 23 | + - schema_ron → Custom RON Schema |
| 24 | + - Neither → Default (zerv-standard) |
| 25 | +``` |
| 26 | + |
| 27 | +## ✅ COMPLETED IMPLEMENTATION |
| 28 | + |
| 29 | +### 1. RON Schema Parser (`src/schema/parser.rs`) |
| 30 | + |
| 31 | +**Features:** |
| 32 | + |
| 33 | +- `SchemaConfig` struct for RON deserialization |
| 34 | +- `ComponentConfig` enum with tagged union support |
| 35 | +- Automatic conversion to `ZervSchema` via `From` traits |
| 36 | +- Comprehensive error handling with `ZervError::SchemaParseError` |
| 37 | + |
| 38 | +```rust |
| 39 | +#[derive(Debug, Deserialize)] |
| 40 | +pub struct SchemaConfig { |
| 41 | + pub core: Vec<ComponentConfig>, |
| 42 | + pub extra_core: Vec<ComponentConfig>, |
| 43 | + pub build: Vec<ComponentConfig>, |
| 44 | +} |
| 45 | + |
| 46 | +#[derive(Debug, Deserialize)] |
| 47 | +#[serde(tag = "type")] |
| 48 | +pub enum ComponentConfig { |
| 49 | + String { value: String }, |
| 50 | + Integer { value: u64 }, |
| 51 | + VarField { field: String }, |
| 52 | + VarTimestamp { pattern: String }, |
| 53 | +} |
| 54 | + |
| 55 | +pub fn parse_ron_schema(ron_str: &str) -> Result<ZervSchema, ZervError> |
| 56 | +``` |
| 57 | + |
| 58 | +### 2. Preset Schemas |
| 59 | + |
| 60 | +#### Standard Schema (`src/schema/presets/standard.rs`) |
| 61 | + |
| 62 | +**State-Based Versioning Tiers:** |
| 63 | + |
| 64 | +- **Tier 1** (Tagged, clean): `major.minor.patch` |
| 65 | +- **Tier 2** (Distance, clean): `major.minor.patch.post<distance>+branch.<commit>` |
| 66 | +- **Tier 3** (Dirty): `major.minor.patch.dev<timestamp>+branch.<distance>.<commit>` |
| 67 | + |
| 68 | +**Functions:** |
| 69 | + |
| 70 | +- `zerv_standard_tier_1()` → Basic semantic version |
| 71 | +- `zerv_standard_tier_2()` → Adds post-release and build metadata |
| 72 | +- `zerv_standard_tier_3()` → Adds development identifier |
| 73 | +- `get_standard_schema(vars)` → Tier-aware selection |
| 74 | + |
| 75 | +#### CalVer Schema (`src/schema/presets/calver.rs`) |
| 76 | + |
| 77 | +**Calendar-Based Versioning Tiers:** |
| 78 | + |
| 79 | +- **Tier 1** (Tagged, clean): `YYYY.MM.DD.patch` |
| 80 | +- **Tier 2** (Distance, clean): `YYYY.MM.DD.patch.post<distance>+branch.<commit>` |
| 81 | +- **Tier 3** (Dirty): `YYYY.MM.DD.patch.dev<timestamp>+branch.<distance>.<commit>` |
| 82 | + |
| 83 | +**Functions:** |
| 84 | + |
| 85 | +- `zerv_calver_tier_1()` → Calendar version with patch |
| 86 | +- `zerv_calver_tier_2()` → Adds post-release and build metadata |
| 87 | +- `zerv_calver_tier_3()` → Adds development identifier |
| 88 | +- `get_calver_schema(vars)` → Tier-aware selection |
| 89 | + |
| 90 | +#### Preset Dispatcher (`src/schema/presets/mod.rs`) |
| 91 | + |
| 92 | +```rust |
| 93 | +pub fn get_preset_schema(name: &str, vars: &ZervVars) -> Option<ZervSchema> { |
| 94 | + match name { |
| 95 | + "zerv-standard" => Some(get_standard_schema(vars)), |
| 96 | + "zerv-calver" => Some(get_calver_schema(vars)), |
| 97 | + _ => None, |
| 98 | + } |
| 99 | +} |
| 100 | +``` |
| 101 | + |
| 102 | +### 3. Main Schema Module (`src/schema/mod.rs`) |
| 103 | + |
| 104 | +**Core Function:** |
| 105 | + |
| 106 | +```rust |
| 107 | +pub fn create_zerv_version( |
| 108 | + vars: ZervVars, |
| 109 | + schema_name: Option<&str>, |
| 110 | + schema_ron: Option<&str>, |
| 111 | +) -> Result<Zerv, ZervError> |
| 112 | +``` |
| 113 | + |
| 114 | +**Logic:** |
| 115 | + |
| 116 | +- Validates mutually exclusive schema parameters |
| 117 | +- Handles custom RON schemas via `parse_ron_schema` |
| 118 | +- Resolves preset schemas via `get_preset_schema` |
| 119 | +- Defaults to "zerv-standard" when no schema specified |
| 120 | +- Returns `Zerv { schema, vars }` object |
| 121 | + |
| 122 | +### 4. Error Handling (`src/error.rs`) |
| 123 | + |
| 124 | +**Added Error Variants:** |
| 125 | + |
| 126 | +```rust |
| 127 | +SchemaParseError(String), // RON parsing failures |
| 128 | +UnknownSchema(String), // Invalid preset names |
| 129 | +ConflictingSchemas(String), // Both schema_name and schema_ron provided |
| 130 | +``` |
| 131 | + |
| 132 | +**Standards Compliance:** |
| 133 | + |
| 134 | +- Uses `ZervError` for all custom errors |
| 135 | +- Implements `Display`, `Error`, and `PartialEq` traits |
| 136 | +- Follows project error handling patterns |
| 137 | + |
| 138 | +### 5. Integration (`src/lib.rs`) |
| 139 | + |
| 140 | +```rust |
| 141 | +pub mod schema; |
| 142 | +``` |
| 143 | + |
| 144 | +### 6. Dependencies (`Cargo.toml`) |
| 145 | + |
| 146 | +```toml |
| 147 | +[dependencies] |
| 148 | +ron = "^0.8" # RON parsing |
| 149 | +serde = { version = "^1.0", features = ["derive"] } # Serialization |
| 150 | + |
| 151 | +[dev-dependencies] |
| 152 | +rstest = "^0.26.0" # Parameterized testing |
| 153 | +``` |
| 154 | + |
| 155 | +## ✅ COMPREHENSIVE TEST COVERAGE |
| 156 | + |
| 157 | +**33 Tests Passing** across all modules: |
| 158 | + |
| 159 | +### Parser Tests (4 tests) |
| 160 | + |
| 161 | +- ✅ Simple schema parsing |
| 162 | +- ✅ Complex schema with all component types |
| 163 | +- ✅ Invalid RON syntax error handling |
| 164 | +- ✅ Component configuration conversion |
| 165 | + |
| 166 | +### Standard Schema Tests (8 tests) |
| 167 | + |
| 168 | +- ✅ Tier determination logic (4 parameterized cases) |
| 169 | +- ✅ Schema generation for each tier (3 tests) |
| 170 | +- ✅ Integration with `get_standard_schema` |
| 171 | + |
| 172 | +### CalVer Schema Tests (8 tests) |
| 173 | + |
| 174 | +- ✅ Tier determination logic (4 parameterized cases) |
| 175 | +- ✅ Schema generation for each tier (3 tests) |
| 176 | +- ✅ Integration with `get_calver_schema` |
| 177 | + |
| 178 | +### Preset Dispatcher Tests (3 tests) |
| 179 | + |
| 180 | +- ✅ Standard schema selection |
| 181 | +- ✅ CalVer schema selection |
| 182 | +- ✅ Unknown schema handling |
| 183 | + |
| 184 | +### Main Module Tests (9 tests) |
| 185 | + |
| 186 | +- ✅ Preset schema integration (6 parameterized cases) |
| 187 | +- ✅ Default schema behavior |
| 188 | +- ✅ Custom RON schema functionality |
| 189 | +- ✅ Error handling (conflicting, unknown, parse errors) |
| 190 | + |
| 191 | +### Core Integration Test (1 test) |
| 192 | + |
| 193 | +- ✅ Empty schema edge case |
| 194 | + |
| 195 | +## Key Architecture Decisions |
| 196 | + |
| 197 | +1. **Functions over Constants**: Schema definitions use functions instead of constants due to Rust's allocation restrictions in const contexts |
| 198 | + |
| 199 | +2. **Correct Field Names**: Uses proper `ZervVars` field names: |
| 200 | + - `current_branch` (not `branch`) |
| 201 | + - `current_commit_hash` (not `commit`) |
| 202 | + |
| 203 | +3. **Tier-Based Logic**: 3-tier system based on Git repository state: |
| 204 | + - **Tier 1**: Clean, tagged state (minimal components) |
| 205 | + - **Tier 2**: Clean with distance (adds post-release metadata) |
| 206 | + - **Tier 3**: Dirty state (adds development identifiers) |
| 207 | + |
| 208 | +4. **Error Standards Compliance**: |
| 209 | + - Uses `ZervError` enum for all custom errors |
| 210 | + - Uses `io::Error::other()` instead of deprecated patterns |
| 211 | + - Includes context in error messages |
| 212 | + |
| 213 | +5. **Comprehensive Testing**: |
| 214 | + - Uses `rstest` for parameterized testing |
| 215 | + - Covers all code paths and error conditions |
| 216 | + - Tests integration between modules |
| 217 | + |
| 218 | +## Usage Examples |
| 219 | + |
| 220 | +### Default Schema |
| 221 | + |
| 222 | +```rust |
| 223 | +let vars = ZervVars { major: Some(1), minor: Some(2), patch: Some(3), ..Default::default() }; |
| 224 | +let zerv = create_zerv_version(vars, None, None)?; // Uses zerv-standard |
| 225 | +``` |
| 226 | + |
| 227 | +### Preset Schema |
| 228 | + |
| 229 | +```rust |
| 230 | +let zerv = create_zerv_version(vars, Some("zerv-calver"), None)?; |
| 231 | +``` |
| 232 | + |
| 233 | +### Custom RON Schema |
| 234 | + |
| 235 | +```rust |
| 236 | +let ron_schema = r#" |
| 237 | + SchemaConfig( |
| 238 | + core: [(type: "VarField", field: "major")], |
| 239 | + extra_core: [], |
| 240 | + build: [(type: "String", value: "custom")] |
| 241 | + ) |
| 242 | +"#; |
| 243 | +let zerv = create_zerv_version(vars, None, Some(ron_schema))?; |
| 244 | +``` |
| 245 | + |
| 246 | +## Next Steps |
| 247 | + |
| 248 | +The schema system is complete and ready for CLI integration. Next implementation phases can focus on: |
| 249 | + |
| 250 | +1. **CLI Commands**: Integrate schema system with `zerv version` and `zerv check` commands |
| 251 | +2. **Output Formats**: Connect schemas to PEP440/SemVer output formatters |
| 252 | +3. **Template System**: Add custom template support for advanced use cases |
| 253 | + |
| 254 | +**All success criteria met. Implementation ready for production use.** |
0 commit comments