props_spread.rs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. use dioxus::core_macro::render;
  2. use dioxus::prelude::rsx;
  3. use dioxus_core::{Attribute, Element, HasAttributesBox, Scope};
  4. use dioxus_html::{ExtendedAudioMarker, ExtendedGlobalAttributesMarker};
  5. #[test]
  6. fn props_spread() {
  7. pub struct FooProps<'a> {
  8. pub open: Option<&'a str>,
  9. attributes: Vec<Attribute<'a>>,
  10. }
  11. // -----
  12. impl<'a> FooProps<'a> {
  13. #[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 "]
  14. #[allow(dead_code)]
  15. pub fn builder(cx: &ScopeState) -> FooPropsBuilder<'a, ((),)> {
  16. FooPropsBuilder {
  17. bump: cx.bump(),
  18. fields: ((),),
  19. attributes: Vec::new(),
  20. _phantom: core::default::Default::default(),
  21. }
  22. }
  23. }
  24. #[must_use]
  25. #[doc(hidden)]
  26. #[allow(dead_code, non_camel_case_types, non_snake_case)]
  27. pub struct FooPropsBuilder<'a, TypedBuilderFields> {
  28. bump: &'a ::dioxus::core::exports::bumpalo::Bump,
  29. fields: TypedBuilderFields,
  30. attributes: Vec<Attribute<'a>>,
  31. _phantom: (core::marker::PhantomData<&'a ()>),
  32. }
  33. //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() } } }
  34. impl<'a> dioxus::prelude::Properties for FooProps<'a> {
  35. type Builder = FooPropsBuilder<'a, ((),)>;
  36. const IS_STATIC: bool = false;
  37. fn builder(cx: &ScopeState) -> Self::Builder {
  38. FooProps::builder(cx)
  39. }
  40. unsafe fn memoize(&self, other: &Self) -> bool {
  41. false
  42. }
  43. }
  44. #[doc(hidden)]
  45. #[allow(dead_code, non_camel_case_types, non_snake_case)]
  46. pub trait FooPropsBuilder_Optional<T> {
  47. fn into_value<F: FnOnce() -> T>(self, default: F) -> T;
  48. }
  49. impl<T> FooPropsBuilder_Optional<T> for () {
  50. fn into_value<F: FnOnce() -> T>(self, default: F) -> T {
  51. default()
  52. }
  53. }
  54. impl<T> FooPropsBuilder_Optional<T> for (T,) {
  55. fn into_value<F: FnOnce() -> T>(self, _: F) -> T {
  56. self.0
  57. }
  58. }
  59. #[allow(dead_code, non_camel_case_types, missing_docs)]
  60. impl<'a> FooPropsBuilder<'a, ((),)> {
  61. pub fn open(
  62. self,
  63. open: &'a str,
  64. ) -> FooPropsBuilder<
  65. 'a,
  66. ((
  67. Option<&'a str>,
  68. // pub attributes: Vec<Attribute<'a>>,
  69. ),),
  70. > {
  71. let open = (Some(open),);
  72. let (_,) = self.fields;
  73. FooPropsBuilder {
  74. bump: self.bump,
  75. fields: (open,),
  76. attributes: self.attributes,
  77. _phantom: self._phantom,
  78. }
  79. }
  80. }
  81. #[doc(hidden)]
  82. #[allow(dead_code, non_camel_case_types, non_snake_case)]
  83. pub enum FooPropsBuilder_Error_Repeated_field_open {}
  84. #[doc(hidden)]
  85. #[allow(dead_code, non_camel_case_types, missing_docs)]
  86. impl<'a>
  87. FooPropsBuilder<
  88. 'a,
  89. ((
  90. Option<&'a str>,
  91. // pub attributes: Vec<Attribute<'a>>,
  92. ),),
  93. >
  94. {
  95. #[deprecated(note = "Repeated field open")]
  96. pub fn open(
  97. self,
  98. _: FooPropsBuilder_Error_Repeated_field_open,
  99. ) -> FooPropsBuilder<
  100. 'a,
  101. ((
  102. Option<&'a str>,
  103. // pub attributes: Vec<Attribute<'a>>,
  104. ),),
  105. > {
  106. self
  107. }
  108. }
  109. #[allow(dead_code, non_camel_case_types, missing_docs)]
  110. impl<'a, __open: FooPropsBuilder_Optional<Option<&'a str>>> FooPropsBuilder<'a, (__open,)> {
  111. pub fn build(self) -> FooProps<'a> {
  112. let (open,) = self.fields;
  113. let open = FooPropsBuilder_Optional::into_value(open, || Default::default());
  114. FooProps {
  115. open,
  116. attributes: self.attributes,
  117. }
  118. }
  119. }
  120. // -----
  121. impl<'a, A> HasAttributesBox<'a, FooPropsBuilder<'a, (A,)>> for FooPropsBuilder<'a, (A,)> {
  122. fn push_attribute(
  123. self,
  124. name: &str,
  125. ns: Option<&str>,
  126. attr: impl IntoAttributeValue<'a>,
  127. volatile: bool,
  128. ) -> Self {
  129. let mut attrs = Vec::from(self.attributes);
  130. attrs.push(Attribute::new(
  131. name,
  132. attr.into_value(self.bump),
  133. ns,
  134. volatile,
  135. ));
  136. FooPropsBuilder {
  137. bump: self.bump,
  138. fields: self.fields,
  139. attributes: attrs,
  140. _phantom: self._phantom,
  141. }
  142. }
  143. }
  144. impl<A> ExtendedGlobalAttributesMarker for FooPropsBuilder<'_, (A,)> {}
  145. impl<A> ExtendedAudioMarker for FooPropsBuilder<'_, (A,)> {}
  146. use dioxus::prelude::*;
  147. use dioxus_html::AudioExtension;
  148. #[allow(non_snake_case)]
  149. pub fn Foo<'a>(cx: Scope<'a, FooProps<'a>>) -> Element<'a> {
  150. let muted = false;
  151. let attributes = &cx.props.attributes;
  152. render! {
  153. // rsx! {
  154. // audio {
  155. // muted: muted,
  156. // }
  157. // }
  158. ::dioxus::core::LazyNodes::new(move |__cx: &::dioxus::core::ScopeState| -> ::dioxus::core::VNode {
  159. static TEMPLATE: ::dioxus::core::Template = ::dioxus::core::Template { name: concat!(file!(), ":", line!(), ":", column!(), ":", "" ), 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]] };
  160. let mut attrs = vec![__cx.attr(dioxus_elements::audio::muted.0, muted, dioxus_elements::audio::muted.1, dioxus_elements::audio::muted.2)];
  161. for attr in attributes {
  162. attrs.push(attr);
  163. }
  164. ::dioxus::core::VNode {
  165. parent: None,
  166. key: None,
  167. template: std::cell::Cell::new(TEMPLATE),
  168. root_ids: Default::default(),
  169. dynamic_nodes: __cx.bump().alloc([]),
  170. dynamic_attrs: __cx.bump().alloc(attrs),
  171. }
  172. })
  173. }
  174. }
  175. rsx! {
  176. Foo {
  177. autoplay: true,
  178. controls: true,
  179. }
  180. };
  181. }