swc_config/
merge.rs

1use std::{collections::HashMap, path::PathBuf};
2
3use indexmap::IndexMap;
4pub use swc_config_macro::Merge;
5
6/// Deriavable trait for overrding configurations.
7///
8/// Typically, correct implementation of this trait for a struct is calling
9/// merge for all fields, and `#[derive(Merge)]` will do it for you.
10pub trait Merge: Sized {
11    /// `self` has higher priority.
12    fn merge(&mut self, other: Self);
13}
14
15/// Modifies `self` iff `self` is [None]
16impl<T> Merge for Option<T> {
17    #[inline]
18    fn merge(&mut self, other: Self) {
19        if self.is_none() {
20            *self = other;
21        }
22    }
23}
24
25impl<T> Merge for Box<T>
26where
27    T: Merge,
28{
29    #[inline]
30    fn merge(&mut self, other: Self) {
31        (**self).merge(*other);
32    }
33}
34
35/// Modifies `self` iff `self` is empty.
36impl<T> Merge for Vec<T> {
37    #[inline]
38    fn merge(&mut self, other: Self) {
39        if self.is_empty() {
40            *self = other;
41        }
42    }
43}
44
45/// Modifies `self` iff `self` is empty.
46impl<K, V, S> Merge for HashMap<K, V, S> {
47    #[inline]
48    fn merge(&mut self, other: Self) {
49        if self.is_empty() {
50            *self = other;
51        }
52    }
53}
54
55/// Modifies `self` iff `self` is empty.
56impl<K, V, S> Merge for IndexMap<K, V, S> {
57    #[inline]
58    fn merge(&mut self, other: Self) {
59        if self.is_empty() {
60            *self = other;
61        }
62    }
63}
64
65/// Modifies `self` iff `self` is empty.
66impl Merge for String {
67    #[inline]
68    fn merge(&mut self, other: Self) {
69        if self.is_empty() {
70            *self = other;
71        }
72    }
73}
74
75/// Modifies `self` iff `self` is empty.
76impl Merge for PathBuf {
77    #[inline]
78    fn merge(&mut self, other: Self) {
79        if self.as_os_str().is_empty() {
80            *self = other;
81        }
82    }
83}