props_spread.rs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. use dioxus::core_macro::render;
  2. use dioxus::prelude::rsx;
  3. use dioxus_core::{AttributeBox, 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<AttributeBox<'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() -> FooPropsBuilder<'a, ((), ), > {
  16. FooPropsBuilder { fields: ((), ), attributes: Vec::new(), _phantom: core::default::Default::default() }
  17. }
  18. }
  19. #[must_use]
  20. #[doc(hidden)]
  21. #[allow(dead_code, non_camel_case_types, non_snake_case)]
  22. pub struct FooPropsBuilder<'a, TypedBuilderFields, > {
  23. fields: TypedBuilderFields,
  24. attributes: Vec<AttributeBox<'a>>,
  25. _phantom: ( core::marker::PhantomData<&'a ()> ),
  26. }
  27. //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() } } }
  28. impl<'a> dioxus::prelude::Properties for FooProps<'a> {
  29. type Builder = FooPropsBuilder<'a, ((), ), >;
  30. const IS_STATIC: bool = false;
  31. fn builder() -> Self::Builder { FooProps::builder() }
  32. unsafe fn memoize(&self, other: &Self) -> bool { false }
  33. }
  34. #[doc(hidden)]
  35. #[allow(dead_code, non_camel_case_types, non_snake_case)]
  36. pub trait FooPropsBuilder_Optional<T> { fn into_value<F: FnOnce() -> T>(self, default: F) -> T; }
  37. impl<T> FooPropsBuilder_Optional<T> for () { fn into_value<F: FnOnce() -> T>(self, default: F) -> T { default() } }
  38. impl<T> FooPropsBuilder_Optional<T> for (T, ) { fn into_value<F: FnOnce() -> T>(self, _: F) -> T { self.0 } }
  39. #[allow(dead_code, non_camel_case_types, missing_docs)]
  40. impl<'a> FooPropsBuilder<'a, ((), )> {
  41. pub fn open(self, open: &'a str) -> FooPropsBuilder<'a, ((Option<&'a str>,
  42. // pub attributes: Vec<Attribute<'a>>,
  43. ), )> {
  44. let open = (Some(open), );
  45. let (_, ) = self.fields;
  46. FooPropsBuilder { fields: (open, ), attributes: self.attributes, _phantom: self._phantom }
  47. }
  48. }
  49. #[doc(hidden)]
  50. #[allow(dead_code, non_camel_case_types, non_snake_case)]
  51. pub enum FooPropsBuilder_Error_Repeated_field_open {}
  52. #[doc(hidden)]
  53. #[allow(dead_code, non_camel_case_types, missing_docs)]
  54. impl<'a> FooPropsBuilder<'a, ((Option<&'a str>,
  55. // pub attributes: Vec<Attribute<'a>>,
  56. ), )> {
  57. #[deprecated(note = "Repeated field open")]
  58. pub fn open(self, _: FooPropsBuilder_Error_Repeated_field_open) -> FooPropsBuilder<'a, ((Option<&'a str>,
  59. // pub attributes: Vec<Attribute<'a>>,
  60. ), )> { self }
  61. }
  62. #[allow(dead_code, non_camel_case_types, missing_docs)]
  63. impl<'a, __open: FooPropsBuilder_Optional<Option<&'a str>>> FooPropsBuilder<'a, (__open, ), > {
  64. pub fn build(self) -> FooProps<'a> {
  65. let (open, ) = self.fields;
  66. let open = FooPropsBuilder_Optional::into_value(open, || Default::default());
  67. FooProps { open, attributes: self.attributes }
  68. }
  69. }
  70. // -----
  71. impl<'a, A> HasAttributesBox<'a, FooPropsBuilder<'a, (A, )>> for FooPropsBuilder<'a, (A, )> {
  72. fn push_attribute(self, attr: AttributeBox<'a>) -> FooPropsBuilder<'a, (A, )> {
  73. let mut attrs = Vec::from(self.attributes);
  74. attrs.push(attr);
  75. FooPropsBuilder { fields: self.fields, attributes: attrs, _phantom: self._phantom }
  76. }
  77. }
  78. impl<A,> ExtendedGlobalAttributesMarker for FooPropsBuilder<'_, (A,)> {}
  79. impl<A,> ExtendedAudioMarker for FooPropsBuilder<'_, (A,)> {}
  80. use dioxus::prelude::*;
  81. use dioxus_html::AudioExtension;
  82. #[allow(non_snake_case)]
  83. pub fn Foo<'a>(cx: Scope<'a, FooProps<'a>>) -> Element<'a> {
  84. let muted = false;
  85. let attributes = cx.props.attributes;
  86. render! {
  87. // rsx! {
  88. // audio {
  89. // muted: muted,
  90. // }
  91. // }
  92. ::dioxus::core::LazyNodes::new(move |__cx: &::dioxus::core::ScopeState| -> ::dioxus::core::VNode {
  93. 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]] };
  94. let mut attrs = vec![__cx.attr(dioxus_elements::audio::muted.0, muted, dioxus_elements::audio::muted.1, dioxus_elements::audio::muted.2)];
  95. for attr in attributes {
  96. attrs.push(__cx.attr(attr.name, attr.value.into_value(__cx.bump()), attr.namespace, attr.volatile));
  97. };
  98. ::dioxus::core::VNode {
  99. parent: None,
  100. key: None,
  101. template: std::cell::Cell::new(TEMPLATE),
  102. root_ids: Default::default(),
  103. dynamic_nodes: __cx.bump().alloc([]),
  104. dynamic_attrs: __cx.bump().alloc(attrs),
  105. }
  106. })
  107. }
  108. }
  109. rsx! {
  110. Foo {
  111. autoplay: true,
  112. controls: true,
  113. }
  114. };
  115. }