swc_common/util/
take.rs

1use std::mem::replace;
2
3use crate::{Span, DUMMY_SP};
4
5/// Helper for people who are working on `VisitMut`.
6///
7///
8/// This trait is implemented for ast nodes. If not and you need it, please file
9/// an issue.
10pub trait Take: Sized {
11    fn take(&mut self) -> Self {
12        replace(self, Self::dummy())
13    }
14
15    /// Create a dummy value of this type.
16    fn dummy() -> Self;
17
18    /// Mutate `self` using `op`, which accepts owned data.
19    #[inline]
20    fn map_with_mut<F>(&mut self, op: F)
21    where
22        F: FnOnce(Self) -> Self,
23    {
24        let dummy = Self::dummy();
25        let cur_val = replace(self, dummy);
26        let new_val = op(cur_val);
27        let _dummy = replace(self, new_val);
28    }
29}
30
31impl<T> Take for Option<T> {
32    fn dummy() -> Self {
33        None
34    }
35}
36
37impl<T> Take for Box<T>
38where
39    T: Take,
40{
41    fn dummy() -> Self {
42        Box::new(T::dummy())
43    }
44}
45
46impl<T> Take for Vec<T> {
47    fn dummy() -> Self {
48        Vec::new()
49    }
50}
51
52impl Take for Span {
53    fn dummy() -> Self {
54        DUMMY_SP
55    }
56}
57
58// swc_allocator::nightly_only!(
59//     impl<T> Take for swc_allocator::boxed::Box<T>
60//     where
61//         T: Take,
62//     {
63//         fn dummy() -> Self {
64//             swc_allocator::boxed::Box::new(T::dummy())
65//         }
66//     }
67
68//     impl<T> Take for swc_allocator::vec::Vec<T> {
69//         fn dummy() -> Self {
70//             Default::default()
71//         }
72//     }
73// );