(
txn: &mut T,
context: &mut ApplyContext,
branch_id: BranchId,
leaf_id: LeafId,
after: Option<LeafId>,
kind: TokenKind,
leaf_content: &[u8],
_content: &[u8],
)
| 148 | /// - `ContentOutOfBounds` - The content range is invalid |
| 149 | #[allow(clippy::too_many_arguments)] |
| 150 | fn apply_insert<T: MutCrdtTxnT>( |
| 151 | txn: &mut T, |
| 152 | context: &mut ApplyContext, |
| 153 | branch_id: BranchId, |
| 154 | leaf_id: LeafId, |
| 155 | after: Option<LeafId>, |
| 156 | kind: TokenKind, |
| 157 | leaf_content: &[u8], |
| 158 | _content: &[u8], |
| 159 | ) -> ApplyResult<()> { |
| 160 | // Check for duplicate ID |
| 161 | if txn |
| 162 | .has_leaf(leaf_id) |
| 163 | .map_err(|e| storage_err(e, "checking leaf exists"))? |
| 164 | { |
| 165 | if context.options().allow_duplicate_ids() { |
| 166 | context.record_skipped(); |
| 167 | return Ok(()); |
| 168 | } |
| 169 | return Err(ApplyError::leaf_already_exists(leaf_id)); |
| 170 | } |
| 171 | |
| 172 | // Validate branch exists (optional based on validation settings) |
| 173 | if context.options().validate_references() |
| 174 | && !txn |
| 175 | .has_branch(branch_id) |
| 176 | .map_err(|e| storage_err(e, "checking branch exists"))? |
| 177 | { |
| 178 | return Err(ApplyError::branch_not_found(branch_id)); |
| 179 | } |
| 180 | |
| 181 | // Validate "after" reference if provided |
| 182 | if context.options().validate_references() { |
| 183 | if let Some(after_id) = after { |
| 184 | if !txn |
| 185 | .has_leaf(after_id) |
| 186 | .map_err(|e| storage_err(e, "checking after leaf"))? |
| 187 | { |
| 188 | return Err(ApplyError::leaf_not_found(after_id)); |
| 189 | } |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | // For now, we store the content length as the range |
| 194 | // In a full implementation, we'd compute the actual offset in the content blob |
| 195 | let content_len = leaf_content.len() as u32; |
| 196 | let content_range = 0..content_len; |
| 197 | |
| 198 | // Create and store the leaf |
| 199 | let leaf = Leaf::new(leaf_id, branch_id, kind, content_range); |
| 200 | txn.put_leaf(&leaf, after) |
| 201 | .map_err(|e| storage_err(e, "inserting leaf"))?; |
| 202 | |
| 203 | context.record_leaf_inserted(); |
| 204 | context.record_content_bytes(content_len as u64); |
| 205 | Ok(()) |
| 206 | } |
| 207 |
no test coverage detected