1use dioxus::core::Task;
7
8pub trait AsyncState {
13 type Data;
15 type Error;
17
18 fn is_loading(&self) -> bool;
20
21 fn is_success(&self) -> bool;
23
24 fn is_error(&self) -> bool;
26
27 fn data(&self) -> Option<&Self::Data>;
29
30 fn error(&self) -> Option<&Self::Error>;
32}
33
34#[derive(Clone, PartialEq, Debug)]
36pub enum State<T, E> {
37 Loading { task: Task },
39 Success(T),
41 Error(E),
43}
44
45impl<T, E> AsyncState for State<T, E> {
46 type Data = T;
47 type Error = E;
48
49 fn is_loading(&self) -> bool {
50 matches!(self, State::Loading { task: _ })
51 }
52
53 fn is_success(&self) -> bool {
54 matches!(self, State::Success(_))
55 }
56
57 fn is_error(&self) -> bool {
58 matches!(self, State::Error(_))
59 }
60
61 fn data(&self) -> Option<&T> {
62 match self {
63 State::Success(data) => Some(data),
64 _ => None,
65 }
66 }
67
68 fn error(&self) -> Option<&E> {
69 match self {
70 State::Error(error) => Some(error),
71 _ => None,
72 }
73 }
74}
75
76impl<T, E> State<T, E> {
77 pub fn is_loading(&self) -> bool {
79 <Self as AsyncState>::is_loading(self)
80 }
81
82 pub fn is_success(&self) -> bool {
84 <Self as AsyncState>::is_success(self)
85 }
86
87 pub fn is_error(&self) -> bool {
89 <Self as AsyncState>::is_error(self)
90 }
91
92 pub fn data(&self) -> Option<&T> {
94 <Self as AsyncState>::data(self)
95 }
96
97 pub fn error(&self) -> Option<&E> {
99 <Self as AsyncState>::error(self)
100 }
101
102 pub fn map<U, F>(self, op: F) -> State<U, E>
104 where
105 F: FnOnce(T) -> U,
106 {
107 match self {
108 State::Success(data) => State::Success(op(data)),
109 State::Error(e) => State::Error(e),
110 State::Loading { task } => State::Loading { task },
111 }
112 }
113
114 pub fn map_err<F, O>(self, op: O) -> State<T, F>
116 where
117 O: FnOnce(E) -> F,
118 {
119 match self {
120 State::Success(data) => State::Success(data),
121 State::Error(e) => State::Error(op(e)),
122 State::Loading { task } => State::Loading { task },
123 }
124 }
125
126 pub fn and_then<U, F>(self, op: F) -> State<U, E>
128 where
129 F: FnOnce(T) -> State<U, E>,
130 {
131 match self {
132 State::Success(data) => op(data),
133 State::Error(e) => State::Error(e),
134 State::Loading { task } => State::Loading { task },
135 }
136 }
137}