launch.rs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. //! Launch helper macros for fullstack apps
  2. #![allow(unused)]
  3. use std::any::Any;
  4. use crate::prelude::*;
  5. use dioxus_core::AnyProps;
  6. use dioxus_core::VProps;
  7. /// A builder for a fullstack app.
  8. pub struct LaunchBuilder<Cfg = ()> {
  9. launch_fn: LaunchFn<Cfg>,
  10. contexts: ContextList,
  11. platform_config: Option<Cfg>,
  12. }
  13. pub type LaunchFn<Cfg> = fn(fn() -> Element, ContextList, Cfg);
  14. #[cfg(feature = "fullstack")]
  15. type ContextList = Vec<Box<dyn Fn() -> Box<dyn Any> + Send + Sync>>;
  16. #[cfg(not(feature = "fullstack"))]
  17. type ContextList = Vec<Box<dyn Fn() -> Box<dyn Any>>>;
  18. impl LaunchBuilder {
  19. /// Create a new builder for your application. This will create a launch configuration for the current platform based on the features enabled on the `dioxus` crate.
  20. pub fn new() -> LaunchBuilder<current_platform::Config> {
  21. LaunchBuilder {
  22. launch_fn: current_platform::launch,
  23. contexts: Vec::new(),
  24. platform_config: None,
  25. }
  26. }
  27. /// Launch your web application.
  28. #[cfg(feature = "web")]
  29. pub fn web() -> LaunchBuilder<dioxus_web::Config> {
  30. LaunchBuilder {
  31. launch_fn: dioxus_web::launch::launch,
  32. contexts: Vec::new(),
  33. platform_config: None,
  34. }
  35. }
  36. /// Launch your desktop application.
  37. #[cfg(feature = "desktop")]
  38. pub fn desktop() -> LaunchBuilder<dioxus_desktop::Config> {
  39. LaunchBuilder {
  40. launch_fn: dioxus_desktop::launch::launch,
  41. contexts: Vec::new(),
  42. platform_config: None,
  43. }
  44. }
  45. /// Launch your fullstack application.
  46. #[cfg(feature = "fullstack")]
  47. pub fn fullstack() -> LaunchBuilder<dioxus_fullstack::Config> {
  48. LaunchBuilder {
  49. launch_fn: dioxus_fullstack::launch::launch,
  50. contexts: Vec::new(),
  51. platform_config: None,
  52. }
  53. }
  54. /// Launch your fullstack application.
  55. #[cfg(feature = "mobile")]
  56. pub fn mobile() -> LaunchBuilder<dioxus_mobile::Config> {
  57. LaunchBuilder {
  58. launch_fn: dioxus_mobile::launch::launch,
  59. contexts: Vec::new(),
  60. platform_config: None,
  61. }
  62. }
  63. /// Provide a custom launch function for your application.
  64. ///
  65. /// Useful for third party renderers to tap into the launch builder API without having to reimplement it.
  66. pub fn custom<Cfg>(launch_fn: LaunchFn<Cfg>) -> LaunchBuilder<Cfg> {
  67. LaunchBuilder {
  68. launch_fn,
  69. contexts: Vec::new(),
  70. platform_config: None,
  71. }
  72. }
  73. }
  74. // Fullstack platform builder
  75. impl<Cfg: Default> LaunchBuilder<Cfg> {
  76. #[cfg(feature = "fullstack")]
  77. /// Inject state into the root component's context that is created on the thread that the app is launched on.
  78. pub fn context_provider(
  79. mut self,
  80. state: impl Fn() -> Box<dyn Any> + Send + Sync + 'static,
  81. ) -> Self {
  82. self.contexts
  83. .push(Box::new(state) as Box<dyn Fn() -> Box<dyn Any> + Send + Sync>);
  84. self
  85. }
  86. #[cfg(not(feature = "fullstack"))]
  87. /// Inject state into the root component's context that is created on the thread that the app is launched on.
  88. pub fn context_provider(mut self, state: impl Fn() -> Box<dyn Any> + 'static) -> Self {
  89. self.contexts
  90. .push(Box::new(state) as Box<dyn Fn() -> Box<dyn Any>>);
  91. self
  92. }
  93. #[cfg(feature = "fullstack")]
  94. /// Inject state into the root component's context.
  95. pub fn context(mut self, state: impl Any + Clone + Send + Sync + 'static) -> Self {
  96. self.contexts
  97. .push(Box::new(move || Box::new(state.clone())));
  98. self
  99. }
  100. #[cfg(not(feature = "fullstack"))]
  101. /// Inject state into the root component's context.
  102. pub fn context(mut self, state: impl Any + Clone + 'static) -> Self {
  103. self.contexts
  104. .push(Box::new(move || Box::new(state.clone())));
  105. self
  106. }
  107. /// Provide a platform-specific config to the builder.
  108. pub fn cfg(mut self, config: impl Into<Option<Cfg>>) -> Self {
  109. if let Some(config) = config.into() {
  110. self.platform_config = Some(config);
  111. }
  112. self
  113. }
  114. #[allow(clippy::unit_arg)]
  115. /// Launch the app.
  116. pub fn launch(self, app: fn() -> Element) {
  117. (self.launch_fn)(app, self.contexts, self.platform_config.unwrap_or_default());
  118. }
  119. }
  120. mod current_platform {
  121. #[cfg(all(feature = "desktop", not(feature = "fullstack")))]
  122. pub use dioxus_desktop::launch::*;
  123. #[cfg(feature = "fullstack")]
  124. pub use dioxus_fullstack::launch::*;
  125. #[cfg(all(feature = "web", not(any(feature = "desktop", feature = "fullstack"))))]
  126. pub use dioxus_web::launch::*;
  127. #[cfg(not(any(feature = "desktop", feature = "web", feature = "fullstack")))]
  128. pub type Config = ();
  129. #[cfg(not(any(feature = "desktop", feature = "web", feature = "fullstack")))]
  130. pub fn launch(
  131. root: fn() -> dioxus_core::Element,
  132. contexts: super::ContextList,
  133. platform_config: Config,
  134. ) {
  135. }
  136. }
  137. /// Launch your application without any additional configuration. See [`LaunchBuilder`] for more options.
  138. pub fn launch(app: fn() -> Element) {
  139. LaunchBuilder::new().launch(app)
  140. }
  141. #[cfg(all(feature = "web", not(feature = "fullstack")))]
  142. /// Launch your web application without any additional configuration. See [`LaunchBuilder`] for more options.
  143. pub fn launch_web(app: fn() -> Element) {
  144. LaunchBuilder::web().launch(app)
  145. }
  146. #[cfg(all(feature = "desktop", not(feature = "fullstack")))]
  147. /// Launch your desktop application without any additional configuration. See [`LaunchBuilder`] for more options.
  148. pub fn launch_desktop(app: fn() -> Element) {
  149. LaunchBuilder::desktop().launch(app)
  150. }
  151. #[cfg(feature = "fullstack")]
  152. /// Launch your fullstack application without any additional configuration. See [`LaunchBuilder`] for more options.
  153. pub fn launch_fullstack(app: fn() -> Element) {
  154. LaunchBuilder::fullstack().launch(app)
  155. }