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 } |