fallow_core/plugins/
used_export_rule.rs1use super::{AggregatedPluginResult, CompiledPathRule, PathRule, PluginResult};
5
6impl PluginResult {
7 pub(super) fn push_used_export_rule(
8 &mut self,
9 pattern: impl Into<String>,
10 exports: impl IntoIterator<Item = impl Into<String>>,
11 ) {
12 self.used_exports
13 .push(UsedExportRule::new(pattern, exports));
14 }
15
16 pub(super) fn push_entry_export_credit(
19 &mut self,
20 pattern: impl Into<String>,
21 exports: impl IntoIterator<Item = impl Into<String>>,
22 ) {
23 self.entry_export_credits
24 .push(UsedExportRule::new(pattern, exports));
25 }
26}
27
28#[derive(Debug, Clone, Default, PartialEq, Eq)]
30pub struct UsedExportRule {
31 pub(crate) path: PathRule,
32 pub(crate) exports: Vec<String>,
33}
34
35impl UsedExportRule {
36 #[must_use]
37 pub(crate) fn new(
38 pattern: impl Into<String>,
39 exports: impl IntoIterator<Item = impl Into<String>>,
40 ) -> Self {
41 Self {
42 path: PathRule::new(pattern),
43 exports: exports.into_iter().map(Into::into).collect(),
44 }
45 }
46
47 #[must_use]
48 pub(super) fn from_static(pattern: &'static str, exports: &'static [&'static str]) -> Self {
49 Self::new(pattern, exports.iter().copied())
50 }
51
52 #[must_use]
53 pub(super) fn with_excluded_globs<I, S>(mut self, patterns: I) -> Self
54 where
55 I: IntoIterator<Item = S>,
56 S: Into<String>,
57 {
58 self.path = self.path.with_excluded_globs(patterns);
59 self
60 }
61
62 #[must_use]
63 pub(super) fn with_excluded_regexes<I, S>(mut self, patterns: I) -> Self
64 where
65 I: IntoIterator<Item = S>,
66 S: Into<String>,
67 {
68 self.path = self.path.with_excluded_regexes(patterns);
69 self
70 }
71
72 #[must_use]
73 pub(super) fn with_excluded_segment_regexes<I, S>(mut self, patterns: I) -> Self
74 where
75 I: IntoIterator<Item = S>,
76 S: Into<String>,
77 {
78 self.path = self.path.with_excluded_segment_regexes(patterns);
79 self
80 }
81
82 #[must_use]
83 pub(super) fn prefixed(&self, ws_prefix: &str) -> Self {
84 Self {
85 path: self.path.prefixed(ws_prefix),
86 exports: self.exports.clone(),
87 }
88 }
89}
90
91#[derive(Debug, Clone, PartialEq, Eq)]
93pub struct PluginUsedExportRule {
94 pub(crate) plugin_name: String,
95 pub(crate) rule: UsedExportRule,
96}
97
98impl PluginUsedExportRule {
99 #[must_use]
100 pub(crate) fn new(plugin_name: impl Into<String>, rule: UsedExportRule) -> Self {
101 Self {
102 plugin_name: plugin_name.into(),
103 rule,
104 }
105 }
106
107 #[must_use]
108 pub(super) fn prefixed(&self, ws_prefix: &str) -> Self {
109 Self {
110 plugin_name: self.plugin_name.clone(),
111 rule: self.rule.prefixed(ws_prefix),
112 }
113 }
114}
115
116pub struct ConfigExportCredit<'a> {
129 matchers: Vec<(CompiledPathRule, &'a [String])>,
130}
131
132impl<'a> ConfigExportCredit<'a> {
133 pub fn new(
135 plugin_result: Option<&'a AggregatedPluginResult>,
136 include_entry_exports: bool,
137 ) -> Self {
138 let matchers = plugin_result
139 .filter(|_| include_entry_exports)
140 .map(|pr| {
141 pr.config_export_credits
142 .iter()
143 .filter_map(|rule| {
144 CompiledPathRule::for_used_export_rule(
145 &rule.rule.path,
146 "config export credit pattern",
147 )
148 .map(|matcher| (matcher, rule.rule.exports.as_slice()))
149 })
150 .collect()
151 })
152 .unwrap_or_default();
153 Self { matchers }
154 }
155
156 pub fn is_empty(&self) -> bool {
158 self.matchers.is_empty()
159 }
160
161 pub fn exports_for(&self, path: &str) -> Vec<&'a [String]> {
164 self.matchers
165 .iter()
166 .filter(|(matcher, _)| matcher.matches(path))
167 .map(|(_, exports)| *exports)
168 .collect()
169 }
170
171 pub fn credits(credited: &[&[String]], export_name: &str) -> bool {
175 credited
176 .iter()
177 .any(|exports| exports.iter().any(|e| e == "*" || e == export_name))
178 }
179}