fob_graph/memory/framework.rs
1//! Framework rule methods for ModuleGraph.
2
3use super::super::{Export, ModuleId};
4use super::graph::ModuleGraph;
5use crate::Result;
6
7impl ModuleGraph {
8 /// Apply a custom framework rule.
9 ///
10 /// Framework rules mark exports as framework-used based on naming conventions.
11 /// This prevents false-positive "unused export" warnings.
12 ///
13 /// Note: FrameworkRule::apply is async, so we use tokio::runtime::Handle::current()
14 /// to execute it. This maintains compatibility with the async trait while
15 /// Apply a single framework rule asynchronously.
16 ///
17 /// # Platform Availability
18 ///
19 /// This method is only available on native platforms (not WASM) because it requires
20 /// tokio runtime support.
21 #[cfg(not(target_family = "wasm"))]
22 pub async fn apply_framework_rule(
23 &self,
24 rule: Box<dyn super::super::FrameworkRule>,
25 ) -> Result<()> {
26 rule.apply(self).await
27 }
28
29 /// Apply multiple framework rules asynchronously.
30 ///
31 /// # Platform Availability
32 ///
33 /// This method is only available on native platforms (not WASM) because it requires
34 /// tokio runtime support.
35 #[cfg(not(target_family = "wasm"))]
36 pub async fn apply_framework_rules(
37 &self,
38 rules: Vec<Box<dyn super::super::FrameworkRule>>,
39 ) -> Result<()> {
40 for rule in rules {
41 self.apply_framework_rule(rule).await?;
42 }
43 Ok(())
44 }
45
46 /// Check if a direct dependency exists between two modules.
47 pub fn has_dependency(&self, from: &ModuleId, to: &ModuleId) -> Result<bool> {
48 let deps = self.dependencies(from)?;
49 Ok(deps.contains(to))
50 }
51
52 /// Get all framework-used exports in the graph.
53 pub fn framework_used_exports(&self) -> Result<Vec<(ModuleId, Export)>> {
54 let mut result = Vec::new();
55 let all_modules = self.modules()?;
56
57 for module in all_modules {
58 for export in module.exports.iter() {
59 if export.is_framework_used {
60 result.push((module.id.clone(), export.clone()));
61 }
62 }
63 }
64
65 Ok(result)
66 }
67}