use crate::prelude::*;
use beet_core::prelude::*;
use beet_dom::prelude::*;
use beet_parse::prelude::*;
use syn::visit::Visit;
pub fn import_rsx_snippets_rs(
_: TempNonSendMarker,
macros: Res<TemplateMacros>,
mut commands: Commands,
query: Populated<(Entity, &SourceFile), Added<SourceFile>>,
) -> Result {
for (entity, path) in query.iter() {
if let Some(ex) = path.extension()
&& ex == "rs"
{
trace!("rust source file changed: {}", path.display());
let file = fs_ext::read_to_string(path)?;
let file = syn::parse_file(&file)?;
RsxSynVisitor {
source_file: entity,
commands: &mut commands,
file: &path.into_ws_path()?,
macros: &*macros,
}
.visit_file(&file);
}
}
Ok(())
}
struct RsxSynVisitor<'a, 'w, 's> {
source_file: Entity,
commands: &'a mut Commands<'w, 's>,
file: &'a WsPathBuf,
macros: &'a TemplateMacros,
}
impl<'a, 'w, 's> Visit<'a> for RsxSynVisitor<'a, 'w, 's> {
fn visit_macro(&mut self, mac: &syn::Macro) {
if mac
.path
.segments
.last()
.map_or(false, |seg| *&seg.ident == *self.macros.rstml)
{
let tokens = mac.tokens.clone();
self.commands.spawn((
SnippetRoot::new_from_tokens(self.file.clone(), &tokens),
StaticRoot,
ChildOf(self.source_file),
RstmlTokens::new(tokens),
));
}
}
}
#[cfg(test)]
mod test {
use crate::prelude::*;
use beet_core::prelude::*;
use beet_rsx::prelude::*;
#[test]
fn works() {
let mut world = BuildPlugin::world();
let test_site_index = WsPathBuf::new("tests/test_site/pages/index.rs");
let entity = world
.spawn(SourceFile::new(test_site_index.into_abs()))
.id();
world.run_schedule(ParseSourceFiles);
let child = world.entity(entity).get::<Children>().unwrap()[0];
world
.run_system_cached_with(render_fragment, child)
.unwrap()
.xpect_str("party time!");
}
}