1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use std::fmt::Debug;

/// This struct specifies dependencies for certain hooks.
///
/// # Example
///
/// ```
/// # use wasm_react::{*, hooks::*};
/// # fn log(s: &str) {}
/// # struct State { counter: () }
/// # struct F { id: () };
/// # impl F {
/// #   fn f(&self, state: State) {
/// #
/// use_effect(|| {
///   log("This effect will be called every time `self.id` or `state.counter` changes.");
///
///   || ()
/// }, Deps::some((self.id, state.counter)));
/// #
/// #   }
/// # }
/// ```
#[derive(PartialEq, Clone, Copy)]
pub struct Deps<T>(Option<T>);

impl<T: Debug> Debug for Deps<T> {
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    let mut result = f.debug_tuple("Deps");

    match self.0.as_ref() {
      Some(deps) => result.field(&deps),
      None => result.field(&"All"),
    }
    .finish()
  }
}

impl Deps<()> {
  /// The hook will be activated whenever the component renders.
  pub fn all() -> Self {
    Self(None)
  }

  /// The hook will be activated only on the first render.
  pub fn none() -> Self {
    Self(Some(()))
  }
}

impl<T> Deps<T> {
  /// The hook will be activated every time when the component renders if the
  /// inner value `T` has changed from last render.
  pub fn some(deps: T) -> Self {
    Self(Some(deps))
  }

  pub(crate) fn is_all(&self) -> bool {
    self.0.is_none()
  }
}