1
0

server_future.rs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. use dioxus_core::prelude::*;
  2. use serde::{de::DeserializeOwned, Serialize};
  3. use std::any::Any;
  4. use std::cell::Cell;
  5. use std::cell::Ref;
  6. use std::cell::RefCell;
  7. use std::fmt::Debug;
  8. use std::future::Future;
  9. use std::rc::Rc;
  10. use std::sync::Arc;
  11. /// A future that resolves to a value.
  12. ///
  13. /// This runs the future only once - though the future may be regenerated
  14. /// through the [`UseServerFuture::restart`] method.
  15. ///
  16. /// This is commonly used for components that cannot be rendered until some
  17. /// asynchronous operation has completed.
  18. ///
  19. /// Whenever the hooks dependencies change, the future will be re-evaluated.
  20. /// If a future is pending when the dependencies change, the previous future
  21. /// will be allowed to continue
  22. ///
  23. /// - dependencies: a tuple of references to values that are PartialEq + Clone
  24. #[must_use = "Consider using `cx.spawn` to run a future without reading its value"]
  25. pub fn use_server_future<T, F>(future: impl FnOnce() -> F) -> Option<UseServerFuture<T>>
  26. where
  27. T: 'static + Serialize + DeserializeOwned + Debug,
  28. F: Future<Output = T> + 'static,
  29. {
  30. todo!()
  31. // let state = use_hook(move || UseServerFuture {
  32. // update: schedule_update(),
  33. // needs_regen: Cell::new(true),
  34. // value: Default::default(),
  35. // task: Cell::new(None),
  36. // dependencies: Vec::new(),
  37. // });
  38. // let first_run = { state.value.borrow().as_ref().is_none() && state.task.get().is_none() };
  39. // #[cfg(not(feature = "ssr"))]
  40. // {
  41. // if first_run {
  42. // match crate::html_storage::deserialize::take_server_data() {
  43. // Some(data) => {
  44. // tracing::trace!("Loaded {data:?} from server");
  45. // *state.value.borrow_mut() = Some(Box::new(data));
  46. // state.needs_regen.set(false);
  47. // return Some(state);
  48. // }
  49. // None => {
  50. // tracing::trace!("Failed to load from server... running future");
  51. // }
  52. // };
  53. // }
  54. // }
  55. // if dependencies.clone().apply(&mut state.dependencies) || state.needs_regen.get() {
  56. // // We don't need regen anymore
  57. // state.needs_regen.set(false);
  58. // // Create the new future
  59. // let fut = future(dependencies.out());
  60. // // Clone in our cells
  61. // let value = state.value.clone();
  62. // let schedule_update = state.update.clone();
  63. // // Cancel the current future
  64. // if let Some(current) = state.task.take() {
  65. // cx.remove_future(current);
  66. // }
  67. // state.task.set(Some(cx.push_future(async move {
  68. // let data;
  69. // #[cfg(feature = "ssr")]
  70. // {
  71. // data = fut.await;
  72. // if first_run {
  73. // if let Err(err) = crate::prelude::server_context().push_html_data(&data) {
  74. // tracing::error!("Failed to push HTML data: {}", err);
  75. // };
  76. // }
  77. // }
  78. // #[cfg(not(feature = "ssr"))]
  79. // {
  80. // data = fut.await;
  81. // }
  82. // *value.borrow_mut() = Some(Box::new(data));
  83. // schedule_update();
  84. // })));
  85. // }
  86. // if first_run {
  87. // #[cfg(feature = "ssr")]
  88. // {
  89. // tracing::trace!("Suspending first run of use_server_future");
  90. // cx.suspend();
  91. // }
  92. // None
  93. // } else {
  94. // Some(state)
  95. // }
  96. }
  97. pub struct UseServerFuture<T> {
  98. update: Arc<dyn Fn()>,
  99. needs_regen: Cell<bool>,
  100. task: Cell<Option<Task>>,
  101. dependencies: Vec<Box<dyn Any>>,
  102. value: Rc<RefCell<Option<Box<T>>>>,
  103. }
  104. impl<T> UseServerFuture<T> {
  105. // /// Restart the future with new dependencies.
  106. // ///
  107. // /// Will not cancel the previous future, but will ignore any values that it
  108. // /// generates.
  109. // pub fn restart(&self) {
  110. // self.needs_regen.set(true);
  111. // (self.update)();
  112. // }
  113. // /// Forcefully cancel a future
  114. // pub fn cancel(&self) {
  115. // if let Some(task) = self.task.take() {
  116. // cx.remove_future(task);
  117. // }
  118. // }
  119. // /// Return any value, even old values if the future has not yet resolved.
  120. // ///
  121. // /// If the future has never completed, the returned value will be `None`.
  122. // pub fn value(&self) -> Ref<'_, T> {
  123. // Ref::map(self.value.borrow(), |v| v.as_deref().unwrap())
  124. // }
  125. // /// Get the ID of the future in Dioxus' internal scheduler
  126. // pub fn task(&self) -> Option<Task> {
  127. // self.task.get()
  128. // }
  129. // /// Get the current state of the future.
  130. // pub fn reloading(&self) -> bool {
  131. // self.task.get().is_some()
  132. // }
  133. }