textlane_html/plugins/to_natural_language/
plugin.rs1use std::sync::Arc;
2
3use textlane_core::{
4 Allocator, Attach, Error, File, NaturalLanguageParser, NaturalLanguageParserSlot,
5 Plugin, Transform, Tree, TreeKind,
6};
7
8use crate::actions::hast::bridge::bridge_hast;
9
10#[derive(Clone, Copy, Debug, Default)]
12pub struct ToNaturalLanguage;
13
14struct Bridge {
15 parser: Arc<dyn NaturalLanguageParser>,
16}
17
18impl Plugin for ToNaturalLanguage {
19 fn attach(&self, context: &mut Attach) -> Result<(), Error> {
20 let parser = context
21 .slots_mut()
22 .get::<NaturalLanguageParserSlot>()
23 .and_then(|slot| slot.parser.clone())
24 .ok_or_else(|| {
25 Error::new(
26 "missing-natural-language-parser",
27 "`html.toNaturalLanguage` needs a natural-language parser: build textlane with `nl`",
28 )
29 })?;
30 context.add_transform(Box::new(Bridge { parser }));
31 Ok(())
32 }
33}
34
35impl Transform for Bridge {
36 fn input(&self) -> TreeKind {
37 TreeKind::Hast
38 }
39
40 fn output(&self) -> TreeKind {
41 TreeKind::Nlcst
42 }
43
44 fn run<'a>(
45 &self,
46 tree: Tree<'a>,
47 file: &mut File,
48 alloc: &'a Allocator,
49 ) -> Result<Tree<'a>, Error> {
50 match tree {
51 Tree::Hast(node) => Ok(Tree::Nlcst(bridge_hast(
52 &node,
53 file.value.as_deref().unwrap_or_default(),
54 self.parser.as_ref(),
55 alloc,
56 ))),
57 _ => Err(Error::new(
58 "invalid-stage",
59 "`html.toNaturalLanguage` takes hast",
60 )),
61 }
62 }
63}
64
65#[cfg(test)]
66#[path = "plugin_unit.rs"]
67mod unit;