yew_oauth2/context/
utils.rs

1use super::*;
2use yew::{context::ContextHandle, html::Scope, prelude::*};
3
4/// Helper to get an unzipped version of the context.
5pub trait UnzippedWith {
6    fn unzipped_with(
7        &self,
8        callback: Callback<OAuth2Context>,
9    ) -> (Option<OAuth2Context>, Option<ContextHandle<OAuth2Context>>);
10}
11
12/// Helper to get an unzipped version of the context.
13pub trait Unzipped {
14    type Message;
15
16    fn unzipped<F>(&self, f: F) -> (Option<OAuth2Context>, Option<ContextHandle<OAuth2Context>>)
17    where
18        F: Fn(OAuth2Context) -> Self::Message + 'static;
19}
20
21impl<C> UnzippedWith for Context<C>
22where
23    C: Component,
24{
25    fn unzipped_with(
26        &self,
27        callback: Callback<OAuth2Context>,
28    ) -> (Option<OAuth2Context>, Option<ContextHandle<OAuth2Context>>) {
29        self.link().unzipped_with(callback)
30    }
31}
32
33impl<C> UnzippedWith for Scope<C>
34where
35    C: Component,
36{
37    fn unzipped_with(
38        &self,
39        callback: Callback<OAuth2Context>,
40    ) -> (Option<OAuth2Context>, Option<ContextHandle<OAuth2Context>>) {
41        match self.context(callback) {
42            Some((auth, handle)) => (Some(auth), Some(handle)),
43            None => (None, None),
44        }
45    }
46}
47
48impl<C> Unzipped for Context<C>
49where
50    C: Component,
51{
52    type Message = C::Message;
53
54    fn unzipped<F>(&self, f: F) -> (Option<OAuth2Context>, Option<ContextHandle<OAuth2Context>>)
55    where
56        F: Fn(OAuth2Context) -> Self::Message + 'static,
57    {
58        self.link().unzipped(f)
59    }
60}
61
62impl<C> Unzipped for Scope<C>
63where
64    C: Component,
65{
66    type Message = C::Message;
67
68    fn unzipped<F>(&self, f: F) -> (Option<OAuth2Context>, Option<ContextHandle<OAuth2Context>>)
69    where
70        F: Fn(OAuth2Context) -> Self::Message + 'static,
71    {
72        self.unzipped_with(self.callback(f))
73    }
74}
75
76/// Functional component for using the context.
77pub trait UseContext {
78    type Message;
79
80    fn use_context<T, F>(&self, f: F) -> ContextValue<T>
81    where
82        T: 'static + Clone + PartialEq,
83        F: Fn(T) -> Self::Message + 'static;
84}
85
86impl<C> UseContext for Scope<C>
87where
88    C: Component,
89{
90    type Message = C::Message;
91
92    fn use_context<T, F>(&self, f: F) -> ContextValue<T>
93    where
94        T: 'static + Clone + PartialEq,
95        F: Fn(T) -> Self::Message + 'static,
96    {
97        self.context::<T>(self.callback(f)).into()
98    }
99}
100
101impl<C> UseContext for Context<C>
102where
103    C: Component,
104{
105    type Message = C::Message;
106
107    fn use_context<T, F>(&self, f: F) -> ContextValue<T>
108    where
109        T: 'static + Clone + PartialEq,
110        F: Fn(T) -> Self::Message + 'static,
111    {
112        self.link().use_context(f)
113    }
114}
115
116/// A helper which holds both value and handle in a way that it can easily be updated if it
117/// is present.
118pub enum ContextValue<T>
119where
120    T: 'static + Clone + PartialEq,
121{
122    Some(T, ContextHandle<T>),
123    None,
124}
125
126impl<T> From<Option<(T, ContextHandle<T>)>> for ContextValue<T>
127where
128    T: 'static + Clone + PartialEq,
129{
130    fn from(value: Option<(T, ContextHandle<T>)>) -> Self {
131        match value {
132            Some(value) => Self::Some(value.0, value.1),
133            None => Self::None,
134        }
135    }
136}
137
138impl<T> ContextValue<T>
139where
140    T: 'static + Clone + PartialEq,
141{
142    /// Set a new value, only if the handle is present.
143    pub fn set(&mut self, new_value: T) {
144        match self {
145            Self::Some(value, _) => *value = new_value,
146            Self::None => {}
147        }
148    }
149
150    /// Get the current value.
151    pub fn get(&self) -> Option<&T> {
152        match &self {
153            Self::Some(value, _) => Some(value),
154            Self::None => None,
155        }
156    }
157
158    pub fn as_ref(&self) -> Option<&T> {
159        self.get()
160    }
161}