text_node.rs 2.4 KB

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