Applies a Move operation to rename or relocate a file. # Behavior 1. Verifies the trunk exists 2. Verifies the trunk is alive (not deleted) 3. Checks the new path isn't already taken 4. Updates the trunk's path 5. Updates the PATH_TRUNK index # Errors - `TrunkNotFound` - The trunk doesn't exist - `InvalidTrunkState` - The trunk is deleted - `PathAlreadyExists` - The new path is occupied
(
txn: &mut T,
context: &mut ApplyContext,
trunk_id: TrunkId,
new_path: &str,
)
| 204 | /// - `InvalidTrunkState` - The trunk is deleted |
| 205 | /// - `PathAlreadyExists` - The new path is occupied |
| 206 | fn apply_move<T: MutCrdtTxnT>( |
| 207 | txn: &mut T, |
| 208 | context: &mut ApplyContext, |
| 209 | trunk_id: TrunkId, |
| 210 | new_path: &str, |
| 211 | ) -> ApplyResult<()> { |
| 212 | // Verify trunk exists |
| 213 | let trunk = txn |
| 214 | .get_trunk(trunk_id) |
| 215 | .map_err(|e| storage_err(e, "getting trunk"))? |
| 216 | .ok_or_else(|| ApplyError::trunk_not_found(trunk_id))?; |
| 217 | |
| 218 | // Check current state |
| 219 | if trunk.state().is_deleted() { |
| 220 | return Err(ApplyError::invalid_trunk_state(trunk_id, "deleted", "move")); |
| 221 | } |
| 222 | |
| 223 | // Check for path collision (unless it's the same trunk) |
| 224 | if let Some(existing) = txn |
| 225 | .get_trunk_by_path(new_path) |
| 226 | .map_err(|e| storage_err(e, "checking path exists"))? |
| 227 | { |
| 228 | if existing != trunk_id { |
| 229 | return Err(ApplyError::path_already_exists(new_path, existing)); |
| 230 | } |
| 231 | // Moving to same path is a no-op |
| 232 | context.record_skipped(); |
| 233 | return Ok(()); |
| 234 | } |
| 235 | |
| 236 | // Update path |
| 237 | txn.update_trunk_path(trunk_id, new_path) |
| 238 | .map_err(|e| storage_err(e, "updating trunk path"))?; |
| 239 | |
| 240 | context.record_trunk_moved(); |
| 241 | Ok(()) |
| 242 | } |
| 243 | |
| 244 | // Undelete Operation |
| 245 |
no test coverage detected