rust/hg-core/src/utils.rs
changeset 49934 83437ad8fe3d
parent 49930 e98fd81bb151
child 49979 f5b168979626
equal deleted inserted replaced
49933:be3b545c5cff 49934:83437ad8fe3d
   289     let s = b"before $SOME_LONG_NAME_THAT_WE_ASSUME_IS_NOT_AN_ACTUAL_ENV_VAR after";
   289     let s = b"before $SOME_LONG_NAME_THAT_WE_ASSUME_IS_NOT_AN_ACTUAL_ENV_VAR after";
   290     assert_eq!(expand_vars(s), &s[..]);
   290     assert_eq!(expand_vars(s), &s[..]);
   291 }
   291 }
   292 
   292 
   293 pub(crate) enum MergeResult<V> {
   293 pub(crate) enum MergeResult<V> {
   294     LeftValue,
   294     Left,
   295     RightValue,
   295     Right,
   296     NewValue(V),
   296     New(V),
   297 }
   297 }
   298 
   298 
   299 /// Return the union of the two given maps,
   299 /// Return the union of the two given maps,
   300 /// calling `merge(key, left_value, right_value)` to resolve keys that exist in
   300 /// calling `merge(key, left_value, right_value)` to resolve keys that exist in
   301 /// both.
   301 /// both.
   332     } else if left.len() < right.len() / 2 {
   332     } else if left.len() < right.len() / 2 {
   333         // Same as above but with `left` and `right` swapped
   333         // Same as above but with `left` and `right` swapped
   334         ordmap_union_with_merge_by_iter(right, left, |key, a, b| {
   334         ordmap_union_with_merge_by_iter(right, left, |key, a, b| {
   335             // Also swapped in `merge` arguments:
   335             // Also swapped in `merge` arguments:
   336             match merge(key, b, a) {
   336             match merge(key, b, a) {
   337                 MergeResult::NewValue(v) => MergeResult::NewValue(v),
   337                 MergeResult::New(v) => MergeResult::New(v),
   338                 // … and swap back in `merge` result:
   338                 // … and swap back in `merge` result:
   339                 MergeResult::LeftValue => MergeResult::RightValue,
   339                 MergeResult::Left => MergeResult::Right,
   340                 MergeResult::RightValue => MergeResult::LeftValue,
   340                 MergeResult::Right => MergeResult::Left,
   341             }
   341             }
   342         })
   342         })
   343     } else {
   343     } else {
   344         // For maps of similar size, use the algorithm based on `OrdMap::diff`
   344         // For maps of similar size, use the algorithm based on `OrdMap::diff`
   345         ordmap_union_with_merge_by_diff(left, right, merge)
   345         ordmap_union_with_merge_by_diff(left, right, merge)
   360         match left.get(&key) {
   360         match left.get(&key) {
   361             None => {
   361             None => {
   362                 left.insert(key, right_value);
   362                 left.insert(key, right_value);
   363             }
   363             }
   364             Some(left_value) => match merge(&key, left_value, &right_value) {
   364             Some(left_value) => match merge(&key, left_value, &right_value) {
   365                 MergeResult::LeftValue => {}
   365                 MergeResult::Left => {}
   366                 MergeResult::RightValue => {
   366                 MergeResult::Right => {
   367                     left.insert(key, right_value);
   367                     left.insert(key, right_value);
   368                 }
   368                 }
   369                 MergeResult::NewValue(new_value) => {
   369                 MergeResult::New(new_value) => {
   370                     left.insert(key, new_value);
   370                     left.insert(key, new_value);
   371                 }
   371                 }
   372             },
   372             },
   373         }
   373         }
   374     }
   374     }
   389     // in order to turn it into the union.
   389     // in order to turn it into the union.
   390     //
   390     //
   391     // TODO: if/when https://github.com/bodil/im-rs/pull/168 is accepted,
   391     // TODO: if/when https://github.com/bodil/im-rs/pull/168 is accepted,
   392     // change these from `Vec<(K, V)>` to `Vec<(&K, Cow<V>)>`
   392     // change these from `Vec<(K, V)>` to `Vec<(&K, Cow<V>)>`
   393     // with `left_updates` only borrowing from `right` and `right_updates` from
   393     // with `left_updates` only borrowing from `right` and `right_updates` from
   394     // `left`, and with `Cow::Owned` used for `MergeResult::NewValue`.
   394     // `left`, and with `Cow::Owned` used for `MergeResult::New`.
   395     //
   395     //
   396     // This would allow moving all `.clone()` calls to after we’ve decided
   396     // This would allow moving all `.clone()` calls to after we’ve decided
   397     // which of `right_updates` or `left_updates` to use
   397     // which of `right_updates` or `left_updates` to use
   398     // (value ones becoming `Cow::into_owned`),
   398     // (value ones becoming `Cow::into_owned`),
   399     // and avoid making clones we don’t end up using.
   399     // and avoid making clones we don’t end up using.
   410             }
   410             }
   411             DiffItem::Update {
   411             DiffItem::Update {
   412                 old: (key, left_value),
   412                 old: (key, left_value),
   413                 new: (_, right_value),
   413                 new: (_, right_value),
   414             } => match merge(key, left_value, right_value) {
   414             } => match merge(key, left_value, right_value) {
   415                 MergeResult::LeftValue => {
   415                 MergeResult::Left => {
   416                     right_updates.push((key.clone(), left_value.clone()))
   416                     right_updates.push((key.clone(), left_value.clone()))
   417                 }
   417                 }
   418                 MergeResult::RightValue => {
   418                 MergeResult::Right => {
   419                     left_updates.push((key.clone(), right_value.clone()))
   419                     left_updates.push((key.clone(), right_value.clone()))
   420                 }
   420                 }
   421                 MergeResult::NewValue(new_value) => {
   421                 MergeResult::New(new_value) => {
   422                     left_updates.push((key.clone(), new_value.clone()));
   422                     left_updates.push((key.clone(), new_value.clone()));
   423                     right_updates.push((key.clone(), new_value))
   423                     right_updates.push((key.clone(), new_value))
   424                 }
   424                 }
   425             },
   425             },
   426         }
   426         }