dioxus_rsx/
text_node.rs

1use crate::{literal::HotLiteral, location::DynIdx, HotReloadFormattedSegment, IfmtInput};
2use proc_macro2::{Span, TokenStream as TokenStream2};
3use quote::ToTokens;
4use quote::{quote, TokenStreamExt};
5use syn::Result;
6use syn::{
7    parse::{Parse, ParseStream},
8    LitStr,
9};
10
11#[derive(PartialEq, Eq, Clone, Debug, Hash)]
12pub struct TextNode {
13    pub input: HotReloadFormattedSegment,
14    pub dyn_idx: DynIdx,
15}
16
17impl Parse for TextNode {
18    fn parse(input: ParseStream) -> Result<Self> {
19        Ok(Self {
20            input: input.parse()?,
21            dyn_idx: DynIdx::default(),
22        })
23    }
24}
25
26impl ToTokens for TextNode {
27    fn to_tokens(&self, tokens: &mut TokenStream2) {
28        let txt = &self.input;
29
30        if txt.is_static() {
31            tokens.append_all(quote! {
32                dioxus_core::DynamicNode::Text(dioxus_core::VText::new(#txt.to_string()))
33            })
34        } else {
35            // todo:
36            // Use the RsxLiteral implementation to spit out a hotreloadable variant of this string
37            // This is not super efficient since we're doing a bit of cloning
38            let as_lit = HotLiteral::Fmted(txt.clone());
39
40            tokens.append_all(quote! {
41                dioxus_core::DynamicNode::Text(dioxus_core::VText::new( #as_lit ))
42            })
43        }
44    }
45}
46
47impl TextNode {
48    pub fn from_text(text: &str) -> Self {
49        let ifmt = IfmtInput {
50            source: LitStr::new(text, Span::call_site()),
51            segments: vec![],
52        };
53        Self {
54            input: ifmt.into(),
55            dyn_idx: Default::default(),
56        }
57    }
58
59    pub fn is_static(&self) -> bool {
60        self.input.is_static()
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67    use prettier_please::PrettyUnparse;
68
69    #[test]
70    fn parses() {
71        let input = syn::parse2::<TextNode>(quote! { "hello world" }).unwrap();
72        assert_eq!(input.input.source.value(), "hello world");
73    }
74
75    #[test]
76    fn to_tokens_with_hr() {
77        let lit = syn::parse2::<TextNode>(quote! { "hi {world1} {world2} {world3}" }).unwrap();
78        println!("{}", lit.to_token_stream().pretty_unparse());
79    }
80
81    #[test]
82    fn raw_str() {
83        let input = syn::parse2::<TextNode>(quote! { r#"hello world"# }).unwrap();
84        println!("{}", input.input.source.to_token_stream());
85        assert_eq!(input.input.source.value(), "hello world");
86    }
87}