component.rs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. //! This file handles the supporting infrastructure for the `Component` trait and `Properties` which makes it possible
  2. //! for components to be used within Nodes.
  3. //!
  4. //! Note - using the builder pattern does not required the Properties trait to be implemented - the only thing that matters is
  5. //! if the type suppports PartialEq. The Properties trait is used by the rsx! and html! macros to generate the type-safe builder
  6. //! that ensures compile-time required and optional fields on ctx.
  7. use crate::innerlude::FC;
  8. pub type ScopeIdx = generational_arena::Index;
  9. pub unsafe trait Properties: PartialEq + Sized {
  10. type Builder;
  11. const CAN_BE_MEMOIZED: bool;
  12. fn builder() -> Self::Builder;
  13. }
  14. pub struct EmptyBuilder;
  15. impl EmptyBuilder {
  16. pub fn build(self) -> () {
  17. ()
  18. }
  19. }
  20. unsafe impl Properties for () {
  21. const CAN_BE_MEMOIZED: bool = true;
  22. type Builder = EmptyBuilder;
  23. fn builder() -> Self::Builder {
  24. EmptyBuilder {}
  25. }
  26. }
  27. pub fn fc_to_builder<T: Properties>(_f: FC<T>) -> T::Builder {
  28. T::builder()
  29. }
  30. mod testing {
  31. use std::{any::Any, ops::Deref};
  32. use crate::innerlude::VNode;
  33. // trait PossibleProps {
  34. // type POut: PartialEq;
  35. // fn as_partial_eq(&self) -> Option<&Self::POut> {
  36. // None
  37. // }
  38. // }
  39. // impl<T: PartialEq> PossibleProps for T {
  40. // type POut = Self;
  41. // }
  42. // struct SomeProps2<'a> {
  43. // inner: &'a str,
  44. // }
  45. // Fallback trait for to all types to default to `false`.
  46. trait NotEq {
  47. const IS_EQ: bool = false;
  48. }
  49. impl<T> NotEq for T {}
  50. // Concrete wrapper type where `IS_COPY` becomes `true` if `T: Copy`.
  51. struct IsEq<G, T>(std::marker::PhantomData<(G, T)>);
  52. impl<G: PartialEq, T: PartialEq<G>> IsEq<G, T> {
  53. // Because this is implemented directly on `IsCopy`, it has priority over
  54. // the `NotCopy` trait impl.
  55. //
  56. // Note: this is a *totally different* associated constant from that in
  57. // `NotCopy`. This does not specialize the `NotCopy` trait impl on `IsCopy`.
  58. const IS_EQ: bool = true;
  59. }
  60. #[derive(PartialEq)]
  61. struct SomeProps {
  62. inner: &'static str,
  63. }
  64. struct SomeProps2 {
  65. inner: &'static str,
  66. }
  67. #[test]
  68. fn test() {
  69. let g = IsEq::<SomeProps, SomeProps>::IS_EQ;
  70. // let g = IsEq::<Vec<u32>>::IS_COPY;
  71. // let g = IsEq::<u32>::IS_COPY;
  72. // dbg!(g);
  73. // let props = SomeProps { inner: "asd" };
  74. // let intermediate: Box<dyn PartialEq<SomeProps>> = Box::new(props);
  75. // let as_any: Box<dyn Any> = Box::new(intermediate);
  76. // let as_partialeq = as_any
  77. // .downcast_ref::<Box<dyn PartialEq<SomeProps>>>()
  78. // .unwrap();
  79. }
  80. // struct blah {}
  81. // #[reorder_args]
  82. pub fn blah(a: i32, b: &str, c: &str) {}
  83. // pub mod blah {
  84. // pub const a: u8 = 0;
  85. // pub const b: u8 = 1;
  86. // }
  87. trait Eat {}
  88. impl Eat for fn() {}
  89. impl<T> Eat for fn(T) {}
  90. impl<T, K> Eat for fn(T, K) {}
  91. mod other {
  92. use super::blah;
  93. fn test2() {
  94. // rsx!{
  95. // div {
  96. // Ele {
  97. // a: 10,
  98. // b: "asd"
  99. // c: impl Fn() -> ()
  100. // }
  101. // }
  102. // }
  103. // becomes
  104. // const reorder: fn(_, _) = |a, b| {};
  105. // blah::META;
  106. // let a = 10;
  107. // let b = "asd";
  108. // let g = [10, 10.0];
  109. // let c = g.a;
  110. // blah(10, "asd");
  111. }
  112. }
  113. struct Inner<'a> {
  114. a: String,
  115. b: i32,
  116. c: &'a str,
  117. }
  118. struct Custom<'a, P: 'a> {
  119. inner: &'a P,
  120. // inner: *const (),
  121. _p: std::marker::PhantomData<&'a P>,
  122. }
  123. impl<'a, P> Custom<'a, P> {
  124. fn props(&self) -> &P {
  125. todo!()
  126. }
  127. }
  128. // impl<P> Deref for Custom<P> {
  129. // type Target = Inner;
  130. // fn deref(&self) -> &Self::Target {
  131. // unsafe { &*self.inner }
  132. // }
  133. // }
  134. fn test2<'a>(a: Custom<'a, Inner<'a>>) -> VNode {
  135. let r = a.inner;
  136. todo!()
  137. // let g = a.props();
  138. // todo!()
  139. // let g = &a.a;
  140. }
  141. fn is_comp() {}
  142. }
  143. mod style {}