spread.rs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. //! Example: SSR
  2. //!
  3. //! This example shows how we can render the Dioxus Virtualdom using SSR.
  4. use dioxus::core::{Attribute, HasAttributesBox};
  5. use dioxus::html::GlobalAttributesExtension;
  6. use dioxus::html::{AudioExtension, ExtendedAudioMarker, ExtendedGlobalAttributesMarker};
  7. use dioxus::prelude::*;
  8. fn main() {
  9. // We can render VirtualDoms
  10. let mut vdom = VirtualDom::new(app);
  11. let _ = vdom.rebuild();
  12. println!("{}", dioxus_ssr::render(&vdom));
  13. }
  14. fn app(cx: Scope) -> Element {
  15. cx.render(rsx!(Foo {
  16. autoplay: true,
  17. controls: true,
  18. src: "https://www.w3schools.com/tags/horse.ogg",
  19. width: "100",
  20. }))
  21. }
  22. pub struct FooProps<'a> {
  23. pub open: Option<&'a str>,
  24. attributes: Vec<Attribute<'a>>,
  25. }
  26. // -----
  27. impl<'a> FooProps<'a> {
  28. #[doc = "\nCreate a builder for building `FooProps`.\nOn the builder, call `.open(...)`(optional) to set the values of the fields.\nFinally, call `.build()` to create the instance of `FooProps`.\n "]
  29. #[allow(dead_code)]
  30. pub fn builder(cx: &'a ScopeState) -> FooPropsBuilder<'a, ((),)> {
  31. FooPropsBuilder {
  32. bump: cx.bump(),
  33. fields: ((),),
  34. attributes: Vec::new(),
  35. _phantom: core::default::Default::default(),
  36. }
  37. }
  38. }
  39. #[must_use]
  40. #[doc(hidden)]
  41. #[allow(dead_code, non_camel_case_types, non_snake_case)]
  42. pub struct FooPropsBuilder<'a, TypedBuilderFields> {
  43. bump: &'a ::dioxus::core::exports::bumpalo::Bump,
  44. fields: TypedBuilderFields,
  45. attributes: Vec<Attribute<'a>>,
  46. _phantom: core::marker::PhantomData<&'a ()>,
  47. }
  48. //impl<'a, TypedBuilderFields, > Clone for FooPropsBuilder<'a, TypedBuilderFields, > where TypedBuilderFields: Clone { fn clone(&self) -> Self { Self { fields: self.fields.clone(), attributes: self.attributes, _phantom: Default::default() } } }
  49. impl<'a> dioxus::prelude::Properties<'a> for FooProps<'a> {
  50. type Builder = FooPropsBuilder<'a, ((),)>;
  51. const IS_STATIC: bool = false;
  52. fn builder(cx: &'a ScopeState) -> Self::Builder {
  53. FooProps::builder(cx)
  54. }
  55. unsafe fn memoize(&self, _other: &Self) -> bool {
  56. false
  57. }
  58. }
  59. #[doc(hidden)]
  60. #[allow(dead_code, non_camel_case_types, non_snake_case)]
  61. pub trait FooPropsBuilder_Optional<T> {
  62. fn into_value<F: FnOnce() -> T>(self, default: F) -> T;
  63. }
  64. impl<T> FooPropsBuilder_Optional<T> for () {
  65. fn into_value<F: FnOnce() -> T>(self, default: F) -> T {
  66. default()
  67. }
  68. }
  69. impl<T> FooPropsBuilder_Optional<T> for (T,) {
  70. fn into_value<F: FnOnce() -> T>(self, _: F) -> T {
  71. self.0
  72. }
  73. }
  74. #[allow(dead_code, non_camel_case_types, missing_docs)]
  75. impl<'a> FooPropsBuilder<'a, ((),)> {
  76. pub fn open(
  77. self,
  78. open: &'a str,
  79. ) -> FooPropsBuilder<
  80. 'a,
  81. ((
  82. Option<&'a str>,
  83. // pub attributes: Vec<Attribute<'a>>,
  84. ),),
  85. > {
  86. let open = (Some(open),);
  87. let (_,) = self.fields;
  88. FooPropsBuilder {
  89. bump: self.bump,
  90. fields: (open,),
  91. attributes: self.attributes,
  92. _phantom: self._phantom,
  93. }
  94. }
  95. }
  96. #[doc(hidden)]
  97. #[allow(dead_code, non_camel_case_types, non_snake_case)]
  98. pub enum FooPropsBuilder_Error_Repeated_field_open {}
  99. #[doc(hidden)]
  100. #[allow(dead_code, non_camel_case_types, missing_docs)]
  101. impl<'a>
  102. FooPropsBuilder<
  103. 'a,
  104. ((
  105. Option<&'a str>,
  106. // pub attributes: Vec<Attribute<'a>>,
  107. ),),
  108. >
  109. {
  110. #[deprecated(note = "Repeated field open")]
  111. pub fn open(
  112. self,
  113. _: FooPropsBuilder_Error_Repeated_field_open,
  114. ) -> FooPropsBuilder<
  115. 'a,
  116. ((
  117. Option<&'a str>,
  118. // pub attributes: Vec<Attribute<'a>>,
  119. ),),
  120. > {
  121. self
  122. }
  123. }
  124. #[allow(dead_code, non_camel_case_types, missing_docs)]
  125. impl<'a, __open: FooPropsBuilder_Optional<Option<&'a str>>> FooPropsBuilder<'a, (__open,)> {
  126. pub fn build(self) -> FooProps<'a> {
  127. let (open,) = self.fields;
  128. let open = FooPropsBuilder_Optional::into_value(open, || Default::default());
  129. FooProps {
  130. open,
  131. attributes: self.attributes,
  132. }
  133. }
  134. }
  135. // -----
  136. impl<'a, A> HasAttributesBox<'a, FooPropsBuilder<'a, (A,)>> for FooPropsBuilder<'a, (A,)> {
  137. fn push_attribute(
  138. self,
  139. name: &'a str,
  140. ns: Option<&'static str>,
  141. attr: impl IntoAttributeValue<'a>,
  142. volatile: bool,
  143. ) -> Self {
  144. let mut attrs = self.attributes;
  145. // We insert attributes so that the list is binary-searchable
  146. if let Err(index) = attrs.binary_search_by(|probe| probe.name.cmp(name)) {
  147. attrs.insert(
  148. index,
  149. Attribute::new(name, attr.into_value(self.bump), ns, volatile),
  150. );
  151. }
  152. FooPropsBuilder {
  153. bump: self.bump,
  154. fields: self.fields,
  155. attributes: attrs,
  156. _phantom: self._phantom,
  157. }
  158. }
  159. }
  160. impl<A> ExtendedGlobalAttributesMarker for FooPropsBuilder<'_, (A,)> {}
  161. impl<A> ExtendedAudioMarker for FooPropsBuilder<'_, (A,)> {}
  162. #[allow(non_snake_case)]
  163. pub fn Foo<'a>(cx: Scope<'a, FooProps<'a>>) -> Element<'a> {
  164. let attributes = &cx.props.attributes;
  165. render! {
  166. // rsx! {
  167. // audio {
  168. // ...attributes,
  169. // }
  170. // }
  171. ::dioxus::core::LazyNodes::new(move |__cx: &::dioxus::core::ScopeState| -> ::dioxus::core::VNode {
  172. static TEMPLATE: ::dioxus::core::Template = ::dioxus::core::Template { name: concat!(file!(), ":", line!(), ":", column!(), ":", "123" ), roots: &[::dioxus::core::TemplateNode::Element { tag: dioxus_elements::audio::TAG_NAME, namespace: dioxus_elements::audio::NAME_SPACE, attrs: &[::dioxus::core::TemplateAttribute::Dynamic { id: 0usize }], children: &[] }], node_paths: &[], attr_paths: &[&[0u8]] };
  173. let attrs = vec![(&**attributes).into()];
  174. ::dioxus::core::VNode {
  175. parent: None,
  176. key: None,
  177. template: std::cell::Cell::new(TEMPLATE),
  178. root_ids: dioxus::core::exports::bumpalo::collections::Vec::new_in(__cx.bump()).into(),
  179. dynamic_nodes: __cx.bump().alloc([]),
  180. dynamic_attrs: __cx.bump().alloc(attrs),
  181. }
  182. })
  183. }
  184. }