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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
use ;
use NgynContext;
/// Trait to configure a gate, middleware or related service.
///
/// It is useful when you need to pass configuration to a gate, middleware or related service.
///
/// ### Example
///
/// ```rust
/// # use ngyn_shared::WithConfig;
/// # use ngyn_shared::server::NgynContext;
/// # use ngyn_shared::NgynGate;
///
/// struct AuthGateConfig {
/// pub secret: String,
/// }
///
/// impl Default for AuthGateConfig {
/// fn default() -> Self {
/// Self {
/// secret: "my_secret".to_string(),
/// }
/// }
/// }
///
/// struct AuthGate;
///
/// impl WithConfig<AuthGateConfig> for AuthGate {}
///
/// impl NgynGate for AuthGate {
/// async fn can_activate(cx: &mut NgynContext<'_>) -> bool {
/// let config = Self::config();
/// config.secret == "my_secret"
/// }
/// }
/// ```
/// Trait for implementing a gate.
///
/// Gates are how Ngyn determines if a route can activate.
/// Sometimes, a route may need to be guarded by certain conditions.
/// For instance, restricting access to a route based on the user's role, or checking if the user is authenticated.
/// Typically, gates are used for this purpose.
///
/// ### Examples
///
/// ```rust
/// # use ngyn_shared::NgynGate;
/// # use ngyn_shared::server::NgynContext;
///
/// struct AuthGate;
///
/// impl NgynGate for AuthGate {
/// async fn can_activate(cx: &mut NgynContext<'_>) -> bool {
/// // Check if the user is authenticated
/// // If the user is authenticated, return true
/// // Otherwise, return false
/// false
/// }
/// }
/// ```
/// Trait for implementing a middleware.
///
/// Middlewares are how Ngyn processes requests.
/// They can be used to modify the request context, the response, or both.
///
/// A few things to note about middlewares:
/// - They are executed in the order they are added.
/// - They can be used to modify the request context, the response, or both.
/// - They can be used to short-circuit the request handling process.
/// - They are purely synchronous and should not ideally not have side effects.
///
/// ### Examples
///
/// ```rust
/// # use ngyn_shared::NgynMiddleware;
/// # use ngyn_shared::server::NgynContext;
///
/// pub struct RequestReceivedLogger {}
///
/// impl NgynMiddleware for RequestReceivedLogger {
/// async fn handle(cx: &mut NgynContext<'_>) {
/// println!("Request received: {:?}", cx.request());
/// }
/// }
/// ```
pub