summaryrefslogtreecommitdiff
path: root/systems/sheet/src/mapping_pattern.rs
blob: 2b30c0d28cbed87fb4c5cec1233a099697e2c853 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// Mapping Pattern
// 是用来匹配多个 Mapping 的语法
//
// ~ 当前 Sheet
//
// 省略机制
//
// 如果上下文有sheet,那就是
// mapping/file.suffix
//
// 如果没有sheet,那就是
// sheet:/mapping/file.suffix
//
// 可以使用路径语法
//
// sheet:/mapping/../file.suffix
//
// 使用以下逻辑匹配文件
//
// sheet:/. 匹配 sheet 中 / 下所有文件
// sheet:/arts/. 匹配结果为 sheet:/arts/ 下的文件
// sheet:/arts/ 匹配结果为 sheet:/arts/ 下的文件
// sheet:/arts 匹配结果为 sheet:/arts 文件夹
//
// 文件名匹配机制
//
// *.md 匹配所有 md 文件
// [Mm]essages 匹配 Message 或 message
// 使用\[Mm\]essage 匹配 [Mm]essage
// 使用 ** 匹配目录下所有文件(递归)
// 使用 * 匹配目录下所有文件
// 使用 ![XX] 匹配排除以外的所有文件,例如:
//
// ![README.md]* 匹配除名叫 README.md 以外的所有当前目录下的文件
// ![[Rr][Ee][Aa][Dd][Mm][Ee].[Mm][Dd]]** 匹配所有 不叫 README.md 的文件
//
// ![**/temp]** 匹配所有不在temp目录的文件
//
// MappingPattern会根据MappingContext生成MappingPatternResult
// 准确来说是
// PatternResult::Single Or PatternResult::Multi
// PatternResult可以unwrap为single()或multi()

use crate::mapping::MappingBuf;

pub struct MappingPattern {}

#[derive(Debug, PartialEq, Eq, Clone)]
pub enum MappingPatternResult {
    Single(MappingBuf),
    Multi(Vec<MappingBuf>),
}

impl MappingPatternResult {
    pub fn new_single(mapping: MappingBuf) -> Self {
        Self::Single(mapping)
    }

    pub fn new_multi(mappings: Vec<MappingBuf>) -> Self {
        Self::Multi(mappings)
    }

    pub fn is_single(&self) -> bool {
        match self {
            MappingPatternResult::Single(_) => true,
            MappingPatternResult::Multi(_) => false,
        }
    }

    pub fn is_multi(&self) -> bool {
        match self {
            MappingPatternResult::Single(_) => false,
            MappingPatternResult::Multi(_) => true,
        }
    }

    pub fn single(self) -> Option<MappingBuf> {
        match self {
            MappingPatternResult::Single(mapping) => Some(mapping),
            MappingPatternResult::Multi(_) => None,
        }
    }

    pub fn multi(self) -> Option<Vec<MappingBuf>> {
        match self {
            MappingPatternResult::Single(_) => None,
            MappingPatternResult::Multi(mappings) => Some(mappings),
        }
    }

    pub fn ensure_multi(self) -> Vec<MappingBuf> {
        match self {
            MappingPatternResult::Single(mapping) => vec![mapping],
            MappingPatternResult::Multi(mappings) => mappings,
        }
    }

    pub fn unwrap_single(self) -> MappingBuf {
        match self {
            MappingPatternResult::Single(mapping) => mapping,
            MappingPatternResult::Multi(_) => panic!("Called `unwrap_single()` on a `Multi` value"),
        }
    }

    pub fn unwrap_multi(self) -> Vec<MappingBuf> {
        match self {
            MappingPatternResult::Single(_) => {
                panic!("Called `unwrap_multi()` on a `Single` value")
            }
            MappingPatternResult::Multi(mappings) => mappings,
        }
    }

    pub fn unwrap_single_or(self, or: MappingBuf) -> MappingBuf {
        match self {
            MappingPatternResult::Single(mapping) => mapping,
            MappingPatternResult::Multi(_) => or,
        }
    }

    pub fn unwrap_multi_or(self, or: Vec<MappingBuf>) -> Vec<MappingBuf> {
        match self {
            MappingPatternResult::Single(_) => or,
            MappingPatternResult::Multi(mappings) => mappings,
        }
    }

    pub fn unwrap_single_or_else<F>(self, or: F) -> MappingBuf
    where
        F: FnOnce() -> MappingBuf,
    {
        match self {
            MappingPatternResult::Single(mapping) => mapping,
            MappingPatternResult::Multi(_) => or(),
        }
    }

    pub fn unwrap_multi_or_else<F>(self, or: F) -> Vec<MappingBuf>
    where
        F: FnOnce() -> Vec<MappingBuf>,
    {
        match self {
            MappingPatternResult::Single(_) => or(),
            MappingPatternResult::Multi(mappings) => mappings,
        }
    }

    pub fn len(&self) -> usize {
        match self {
            MappingPatternResult::Single(_) => 1,
            MappingPatternResult::Multi(mappings) => mappings.len(),
        }
    }

    pub fn is_empty(&self) -> bool {
        match self {
            MappingPatternResult::Single(_) => false,
            MappingPatternResult::Multi(mappings) => mappings.len() < 1,
        }
    }
}

impl IntoIterator for MappingPatternResult {
    type Item = MappingBuf;
    type IntoIter = std::vec::IntoIter<MappingBuf>;

    fn into_iter(self) -> Self::IntoIter {
        match self {
            MappingPatternResult::Single(m) => vec![m].into_iter(),
            MappingPatternResult::Multi(v) => v.into_iter(),
        }
    }
}