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    /// allowing synchronous callers.
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 fn apply_framework_rule(&self, rule: Box<dyn super::super::FrameworkRule>) -> Result<()> {
23        let handle = tokio::runtime::Handle::try_current().map_err(|_| {
24            crate::Error::InvalidConfig(
25                "FrameworkRule::apply requires a tokio runtime context".to_string(),
26            )
27        })?;
28        handle.block_on(rule.apply(self))
29    }
30
31    /// Apply multiple framework rules.
32    ///
33    /// # Platform Availability
34    ///
35    /// This method is only available on native platforms (not WASM) because it requires
36    /// tokio runtime support.
37    #[cfg(not(target_family = "wasm"))]
38    pub fn apply_framework_rules(
39        &self,
40        rules: Vec<Box<dyn super::super::FrameworkRule>>,
41    ) -> Result<()> {
42        for rule in rules {
43            self.apply_framework_rule(rule)?;
44        }
45        Ok(())
46    }
47
48    /// Check if a direct dependency exists between two modules.
49    pub fn has_dependency(&self, from: &ModuleId, to: &ModuleId) -> Result<bool> {
50        let deps = self.dependencies(from)?;
51        Ok(deps.contains(to))
52    }
53
54    /// Get all framework-used exports in the graph.
55    pub fn framework_used_exports(&self) -> Result<Vec<(ModuleId, Export)>> {
56        let mut result = Vec::new();
57        let all_modules = self.modules()?;
58
59        for module in all_modules {
60            for export in module.exports.iter() {
61                if export.is_framework_used {
62                    result.push((module.id.clone(), export.clone()));
63                }
64            }
65        }
66
67        Ok(result)
68    }
69}