lib_q_core/contexts/
base.rs1#[cfg(feature = "alloc")]
7use alloc::boxed::Box;
8use core::marker::PhantomData;
9
10use crate::api::CryptoProvider;
11use crate::error::Result;
12
13pub trait ContextOps {
15 fn init(&mut self) -> Result<()>;
17
18 fn is_initialized(&self) -> bool;
20
21 fn provider(&self) -> Option<&dyn CryptoProvider>;
23
24 fn set_provider(&mut self, provider: Box<dyn CryptoProvider>);
26}
27
28#[cfg(feature = "alloc")]
30pub struct BaseContext<T> {
31 _phantom: PhantomData<T>,
32 initialized: bool,
33 provider: Option<Box<dyn CryptoProvider>>,
34}
35
36#[cfg(feature = "alloc")]
37impl<T> BaseContext<T> {
38 pub fn new() -> Self {
40 Self {
41 _phantom: PhantomData,
42 initialized: false,
43 provider: None,
44 }
45 }
46
47 pub fn with_provider(provider: Box<dyn CryptoProvider>) -> Self {
49 Self {
50 _phantom: PhantomData,
51 initialized: false,
52 provider: Some(provider),
53 }
54 }
55
56 pub fn init(&mut self) -> Result<()> {
58 if self.initialized {
59 return Ok(());
60 }
61 self.initialized = true;
62 Ok(())
63 }
64
65 pub fn is_initialized(&self) -> bool {
67 self.initialized
68 }
69
70 pub fn provider(&self) -> Option<&dyn CryptoProvider> {
72 self.provider.as_deref()
73 }
74
75 pub fn set_provider(&mut self, provider: Box<dyn CryptoProvider>) {
77 self.provider = Some(provider);
78 }
79
80 pub fn ensure_initialized(&mut self) -> Result<()> {
82 if !self.initialized {
83 self.init()?;
84 }
85 Ok(())
86 }
87}
88
89#[cfg(feature = "alloc")]
90impl<T> Default for BaseContext<T> {
91 fn default() -> Self {
92 Self::new()
93 }
94}
95
96#[cfg(feature = "alloc")]
98pub struct ContextBuilder<T> {
99 provider: Option<Box<dyn CryptoProvider>>,
100 _phantom: PhantomData<T>,
101}
102
103#[cfg(feature = "alloc")]
104impl<T> ContextBuilder<T> {
105 pub fn new() -> Self {
107 Self {
108 provider: None,
109 _phantom: PhantomData,
110 }
111 }
112
113 pub fn with_provider(mut self, provider: Box<dyn CryptoProvider>) -> Self {
115 self.provider = Some(provider);
116 self
117 }
118
119 pub fn build(self) -> BaseContext<T> {
121 match self.provider {
122 Some(provider) => BaseContext::with_provider(provider),
123 None => BaseContext::new(),
124 }
125 }
126}
127
128#[cfg(feature = "alloc")]
129impl<T> Default for ContextBuilder<T> {
130 fn default() -> Self {
131 Self::new()
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138 use crate::api::CryptoProvider;
139
140 struct MockProvider;
142
143 impl CryptoProvider for MockProvider {
144 fn kem(&self) -> Option<&dyn crate::api::KemOperations> {
145 None
146 }
147 fn signature(&self) -> Option<&dyn crate::api::SignatureOperations> {
148 None
149 }
150 fn hash(&self) -> Option<&dyn crate::api::HashOperations> {
151 None
152 }
153 fn aead(&self) -> Option<&dyn crate::api::AeadOperations> {
154 None
155 }
156 }
157
158 #[test]
159 fn test_base_context_creation() {
160 let context = BaseContext::<()>::new();
161 assert!(!context.is_initialized());
162 assert!(context.provider().is_none());
163 }
164
165 #[test]
166 fn test_base_context_with_provider() {
167 let provider = Box::new(MockProvider);
168 let context = BaseContext::<()>::with_provider(provider);
169 assert!(!context.is_initialized());
170 assert!(context.provider().is_some());
171 }
172
173 #[test]
174 fn test_base_context_initialization() {
175 let mut context = BaseContext::<()>::new();
176 assert!(!context.is_initialized());
177
178 let result = context.init();
179 assert!(result.is_ok());
180 assert!(context.is_initialized());
181
182 let result = context.init();
184 assert!(result.is_ok());
185 assert!(context.is_initialized());
186 }
187
188 #[test]
189 fn test_base_context_provider_management() {
190 let mut context = BaseContext::<()>::new();
191 assert!(context.provider().is_none());
192
193 let provider = Box::new(MockProvider);
194 context.set_provider(provider);
195 assert!(context.provider().is_some());
196 }
197
198 #[test]
199 fn test_context_builder() {
200 let provider = Box::new(MockProvider);
201 let context = ContextBuilder::<()>::new().with_provider(provider).build();
202
203 assert!(!context.is_initialized());
204 assert!(context.provider().is_some());
205 }
206
207 #[test]
208 fn test_context_builder_default() {
209 let context = ContextBuilder::<()>::default().build();
210 assert!(!context.is_initialized());
211 assert!(context.provider().is_none());
212 }
213
214 #[test]
215 fn test_ensure_initialized() {
216 let mut context = BaseContext::<()>::new();
217 assert!(!context.is_initialized());
218
219 let result = context.ensure_initialized();
220 assert!(result.is_ok());
221 assert!(context.is_initialized());
222
223 let result = context.ensure_initialized();
225 assert!(result.is_ok());
226 assert!(context.is_initialized());
227 }
228}