lib.rs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #![doc = include_str!("../README.md")]
  2. #![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")]
  3. #![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")]
  4. use component::ComponentBody;
  5. use proc_macro::TokenStream;
  6. use quote::ToTokens;
  7. use syn::parse_macro_input;
  8. mod component;
  9. mod props;
  10. mod utils;
  11. use dioxus_rsx as rsx;
  12. #[proc_macro]
  13. pub fn format_args_f(input: TokenStream) -> TokenStream {
  14. use rsx::*;
  15. format_args_f_impl(parse_macro_input!(input as IfmtInput))
  16. .unwrap_or_else(|err| err.to_compile_error())
  17. .into()
  18. }
  19. #[proc_macro_derive(Props, attributes(props))]
  20. pub fn derive_typed_builder(input: TokenStream) -> TokenStream {
  21. let input = parse_macro_input!(input as syn::DeriveInput);
  22. match props::impl_my_derive(&input) {
  23. Ok(output) => output.into(),
  24. Err(error) => error.to_compile_error().into(),
  25. }
  26. }
  27. /// The rsx! macro makes it easy for developers to write jsx-style markup in their components.
  28. #[proc_macro]
  29. pub fn rsx(tokens: TokenStream) -> TokenStream {
  30. match syn::parse::<rsx::CallBody>(tokens) {
  31. Err(err) => err.to_compile_error().into(),
  32. Ok(body) => body.into_token_stream().into(),
  33. }
  34. }
  35. /// The rsx! macro makes it easy for developers to write jsx-style markup in their components.
  36. ///
  37. /// The render macro automatically renders rsx - making it unhygienic.
  38. #[deprecated(note = "Use `rsx!` instead.")]
  39. #[proc_macro]
  40. pub fn render(tokens: TokenStream) -> TokenStream {
  41. rsx(tokens)
  42. }
  43. /// Streamlines component creation.
  44. /// This is the recommended way of creating components,
  45. /// though you might want lower-level control with more advanced uses.
  46. ///
  47. /// # Arguments
  48. /// * `no_case_check` - Doesn't enforce `PascalCase` on your component names.
  49. /// **This will be removed/deprecated in a future update in favor of a more complete Clippy-backed linting system.**
  50. /// The reasoning behind this is that Clippy allows more robust and powerful lints, whereas
  51. /// macros are extremely limited.
  52. ///
  53. /// # Features
  54. /// This attribute:
  55. /// * Enforces that your component uses `PascalCase`.
  56. /// No warnings are generated for the `PascalCase`
  57. /// function name, but everything else will still raise a warning if it's incorrectly `PascalCase`.
  58. /// Does not disable warnings anywhere else, so if you, for example,
  59. /// accidentally don't use `snake_case`
  60. /// for a variable name in the function, the compiler will still warn you.
  61. /// * Automatically uses `#[inline_props]` if there's more than 1 parameter in the function.
  62. /// * Verifies the validity of your component.
  63. ///
  64. /// # Examples
  65. /// * Without props:
  66. /// ```rust,ignore
  67. /// #[component]
  68. /// fn GreetBob() -> Element {
  69. /// rsx! { "hello, bob" }
  70. /// }
  71. /// ```
  72. ///
  73. /// * With props:
  74. /// ```rust,ignore
  75. /// #[component]
  76. /// fn GreetBob(bob: String) -> Element {
  77. /// rsx! { "hello, {bob}" }
  78. /// }
  79. /// ```
  80. #[proc_macro_attribute]
  81. pub fn component(_args: TokenStream, input: TokenStream) -> TokenStream {
  82. parse_macro_input!(input as ComponentBody)
  83. .into_token_stream()
  84. .into()
  85. }
  86. /// Derive props for a component within the component definition.
  87. ///
  88. /// This macro provides a simple transformation from `Scope<{}>` to `Scope<P>`,
  89. /// removing some boilerplate when defining props.
  90. ///
  91. /// You don't *need* to use this macro at all, but it can be helpful in cases where
  92. /// you would be repeating a lot of the usual Rust boilerplate.
  93. ///
  94. /// # Example
  95. /// ```rust,ignore
  96. /// #[inline_props]
  97. /// fn app(bob: String) -> Element {
  98. /// rsx!("hello, {bob}"))
  99. /// }
  100. ///
  101. /// // is equivalent to
  102. ///
  103. /// #[derive(PartialEq, Props)]
  104. /// struct AppProps {
  105. /// bob: String,
  106. /// }
  107. ///
  108. /// fn app(cx: Scope<AppProps>) -> Element {
  109. /// rsx!("hello, {bob}"))
  110. /// }
  111. /// ```
  112. #[proc_macro_attribute]
  113. #[deprecated(note = "Use `#[component]` instead.")]
  114. pub fn inline_props(args: TokenStream, input: TokenStream) -> TokenStream {
  115. component(args, input)
  116. }