| 301 | } |
| 302 | |
| 303 | pub trait ArrayExt: Array { |
| 304 | fn clear(&self, txn: &mut TransactionMut) { |
| 305 | let len = self.len(txn); |
| 306 | self.remove_range(txn, 0, len); |
| 307 | } |
| 308 | |
| 309 | /// Removes the first element that satisfies the predicate. |
| 310 | fn remove_one<F, V>(&self, txn: &mut TransactionMut, predicate: F) |
| 311 | where |
| 312 | F: Fn(V) -> bool, |
| 313 | V: TryFrom<Out>, |
| 314 | { |
| 315 | let mut i = 0; |
| 316 | while let Some(out) = self.get(txn, i) { |
| 317 | if let Ok(value) = V::try_from(out) { |
| 318 | if predicate(value) { |
| 319 | self.remove(txn, i); |
| 320 | break; |
| 321 | } |
| 322 | } |
| 323 | i += 1; |
| 324 | } |
| 325 | } |
| 326 | |
| 327 | fn update_map<F>(&self, txn: &mut TransactionMut, id: &str, f: F) |
| 328 | where |
| 329 | F: FnOnce(&mut HashMap<String, Any>), |
| 330 | { |
| 331 | let map_ref: MapRef = self.upsert(txn, id); |
| 332 | let mut map = map_ref.to_json(txn).into_map().unwrap(); |
| 333 | f(&mut map); |
| 334 | Any::from(map).fill(txn, &map_ref).unwrap(); |
| 335 | } |
| 336 | |
| 337 | fn index_by_id<T: ReadTxn>(&self, txn: &T, id: &str) -> Option<u32> { |
| 338 | let i = self.iter(txn).position(|value| { |
| 339 | if let Ok(value) = value.cast::<MapRef>() { |
| 340 | if let Some(current_id) = value.get_id(txn) { |
| 341 | return &*current_id == id; |
| 342 | } |
| 343 | } |
| 344 | false |
| 345 | })?; |
| 346 | Some(i as u32) |
| 347 | } |
| 348 | |
| 349 | fn upsert<V>(&self, txn: &mut TransactionMut, id: &str) -> V |
| 350 | where |
| 351 | V: DefaultPrelim + TryFrom<Out>, |
| 352 | { |
| 353 | match self.index_by_id(txn, id) { |
| 354 | None => self.push_back(txn, V::default_prelim()), |
| 355 | Some(i) => { |
| 356 | let out = self.get(txn, i).unwrap(); |
| 357 | match V::try_from(out) { |
| 358 | Ok(shared_ref) => shared_ref, |
| 359 | Err(_) => { |
| 360 | self.remove(txn, i); |
no outgoing calls
no test coverage detected