rocketmq_auth/authentication/context/
base_authentication_context.rs1use std::any::Any;
16use std::collections::HashMap;
17
18use cheetah_string::CheetahString;
19
20use crate::authentication::AsAny;
21use crate::authorization::context::authentication_context::AuthenticationContext;
22
23#[derive(Debug, Default)]
24pub struct BaseAuthenticationContext {
25 channel_id: Option<CheetahString>,
26
27 rpc_code: Option<CheetahString>,
28
29 ext_info: HashMap<CheetahString, Box<dyn Any + Send + Sync>>,
30}
31
32impl BaseAuthenticationContext {
33 pub fn new() -> Self {
34 Self::default()
35 }
36
37 pub fn channel_id(&self) -> Option<&CheetahString> {
38 self.channel_id.as_ref()
39 }
40
41 pub fn set_channel_id(&mut self, channel_id: Option<CheetahString>) {
42 self.channel_id = channel_id;
43 }
44
45 pub fn rpc_code(&self) -> Option<&CheetahString> {
46 self.rpc_code.as_ref()
47 }
48
49 pub fn set_rpc_code(&mut self, rpc_code: Option<CheetahString>) {
50 self.rpc_code = rpc_code;
51 }
52}
53
54impl BaseAuthenticationContext {
55 pub fn get_ext_info<T: 'static>(&self, key: &CheetahString) -> Option<&T> {
56 self.ext_info.get(key).and_then(|v| v.downcast_ref::<T>())
57 }
58 pub fn has_ext_info(&self, key: &CheetahString) -> bool {
59 self.ext_info.contains_key(key)
60 }
61 pub fn ext_info(&self) -> &HashMap<CheetahString, Box<dyn Any + Send + Sync>> {
62 &self.ext_info
63 }
64
65 pub fn ext_info_mut(&mut self) -> &mut HashMap<CheetahString, Box<dyn Any + Send + Sync>> {
66 &mut self.ext_info
67 }
68}
69
70impl BaseAuthenticationContext {
71 pub fn set_ext_info<T>(&mut self, key: CheetahString, value: T)
72 where
73 T: Any + Send + Sync,
74 {
75 self.ext_info.insert(key, Box::new(value));
76 }
77}
78
79impl AuthenticationContext for BaseAuthenticationContext {}
80
81impl AsAny for BaseAuthenticationContext {
82 fn as_any_mut(&mut self) -> &mut dyn Any {
83 self
84 }
85
86 fn as_any(&self) -> &dyn Any {
87 self
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use cheetah_string::CheetahString;
94
95 use crate::authentication::context::base_authentication_context::BaseAuthenticationContext;
96 use crate::authentication::AsAny;
97
98 #[test]
99 fn new_base_authentication_context() {
100 let base_authentication_context = BaseAuthenticationContext::new();
101
102 assert!(base_authentication_context.channel_id().is_none());
103 assert!(base_authentication_context.rpc_code().is_none());
104 assert!(base_authentication_context.ext_info().is_empty());
105 }
106
107 #[test]
108 fn set_and_get_channel_and_rpc() {
109 let mut base_authentication_context = BaseAuthenticationContext::new();
110 base_authentication_context.set_channel_id(Some(CheetahString::from("channel-123")));
111 base_authentication_context.set_rpc_code(Some(CheetahString::from("rpc-456")));
112
113 assert_eq!(
114 Some(&CheetahString::from("channel-123")),
115 base_authentication_context.channel_id()
116 );
117 assert_eq!(
118 Some(&CheetahString::from("rpc-456")),
119 base_authentication_context.rpc_code()
120 );
121 }
122
123 #[test]
124 fn set_get_and_has_ext_info() {
125 let mut base_authentication_context = BaseAuthenticationContext::new();
126 base_authentication_context.set_ext_info(CheetahString::from("info-1"), 123);
127
128 assert!(base_authentication_context.has_ext_info(&CheetahString::from("info-1")));
129 assert_eq!(
130 Some(123),
131 base_authentication_context
132 .get_ext_info::<i32>(&CheetahString::from("info-1"))
133 .copied()
134 );
135 }
136
137 #[test]
138 fn ext_info_nonexistent_key_returns_none() {
139 let base_authentication_context = BaseAuthenticationContext::new();
140
141 assert!(!base_authentication_context.has_ext_info(&CheetahString::from("nonexistent")));
142 assert_eq!(
143 None,
144 base_authentication_context.get_ext_info::<i32>(&CheetahString::from("nonexistent"))
145 );
146 }
147
148 #[test]
149 fn ext_info_wrong_type_returns_none() {
150 let mut base_authentication_context = BaseAuthenticationContext::new();
151 base_authentication_context.set_ext_info(CheetahString::from("info-2"), CheetahString::from("xyz"));
152
153 assert_eq!(
154 None,
155 base_authentication_context
156 .get_ext_info::<u32>(&CheetahString::from("info-2"))
157 .copied()
158 );
159 }
160
161 #[test]
162 fn ext_info_mut_can_modify() {
163 let mut base_authentication_context = BaseAuthenticationContext::new();
164 base_authentication_context
165 .ext_info_mut()
166 .insert(CheetahString::from("info-3"), Box::new(64u32));
167
168 assert_eq!(
169 Some(64u32),
170 base_authentication_context
171 .get_ext_info::<u32>(&CheetahString::from("info-3"))
172 .copied()
173 );
174 }
175
176 #[test]
177 fn as_any_downcasts_work() {
178 let mut base_authentication_context = BaseAuthenticationContext::new();
179
180 let any_ref = base_authentication_context.as_any();
181 assert!(any_ref.downcast_ref::<BaseAuthenticationContext>().is_some());
182
183 let any_mut_ref = base_authentication_context.as_any_mut();
184 assert!(any_mut_ref.downcast_mut::<BaseAuthenticationContext>().is_some());
185 }
186}