rust_prelude_plus/
async_ops.rs

1//! Asynchronous operations for keypath-based functional programming
2
3#[cfg(feature = "async")]
4use {
5    key_paths_core::KeyPaths,
6    crate::error::{KeyPathResult, KeyPathError},
7    crate::traits::KeyPathsOperable,
8};
9
10#[cfg(feature = "async")]
11/// Asynchronous keypath operations for collections
12pub mod async_collections {
13    use super::*;
14    
15    /// Async map over collection with keypath
16    pub async fn map_keypath_async<T, V, F, R>(
17        collection: Vec<T>,
18        keypath: KeyPaths<T, V>,
19        f: F,
20    ) -> KeyPathResult<Vec<R>>
21    where
22        T: Send + Sync + KeyPathsOperable,
23        V: Send + Sync,
24        KeyPaths<T, V>: Send + Sync,
25        F: Fn(&V) -> R + Send + Sync + 'static,
26        R: Send,
27    {
28        let result: Vec<R> = collection
29            .into_iter()
30            .map(|item| {
31                let value = item.get_at_keypath(&keypath).unwrap_or_else(|_| {
32                    panic!("KeyPath access failed in map_keypath_async")
33                });
34                f(value)
35            })
36            .collect();
37        Ok(result)
38    }
39    
40    /// Async filter by keypath predicate
41    pub async fn filter_by_keypath_async<T, V, F>(
42        collection: Vec<T>,
43        keypath: KeyPaths<T, V>,
44        predicate: F,
45    ) -> KeyPathResult<Vec<T>>
46    where
47        T: Send + Sync + KeyPathsOperable,
48        V: Send + Sync,
49        KeyPaths<T, V>: Send + Sync,
50        F: Fn(&V) -> bool + Send + Sync + 'static,
51    {
52        let result: Vec<T> = collection
53            .into_iter()
54            .filter(|item| {
55                let value = item.get_at_keypath(&keypath).unwrap_or_else(|_| {
56                    panic!("KeyPath access failed in filter_by_keypath_async")
57                });
58                predicate(value)
59            })
60            .collect();
61        Ok(result)
62    }
63    
64    /// Async find by keypath predicate
65    pub async fn find_by_keypath_async<T, V, F>(
66        collection: Vec<T>,
67        keypath: KeyPaths<T, V>,
68        predicate: F,
69    ) -> KeyPathResult<Option<T>>
70    where
71        T: Send + Sync + KeyPathsOperable,
72        V: Send + Sync,
73        KeyPaths<T, V>: Send + Sync,
74        F: Fn(&V) -> bool + Send + Sync + 'static,
75    {
76        let result = collection
77            .into_iter()
78            .find(|item| {
79                let value = item.get_at_keypath(&keypath).unwrap_or_else(|_| {
80                    panic!("KeyPath access failed in find_by_keypath_async")
81                });
82                predicate(value)
83            });
84        Ok(result)
85    }
86    
87    /// Async collect keypath values
88    pub async fn collect_keypath_async<T, V>(
89        collection: Vec<T>,
90        keypath: KeyPaths<T, V>,
91    ) -> KeyPathResult<Vec<V>>
92    where
93        T: Send + Sync + KeyPathsOperable,
94        V: Send + Sync + Clone,
95        KeyPaths<T, V>: Send + Sync,
96    {
97        let result: Vec<V> = collection
98            .into_iter()
99            .map(|item| {
100                let value = item.get_at_keypath(&keypath).unwrap_or_else(|_| {
101                    panic!("KeyPath access failed in collect_keypath_async")
102                });
103                value.clone()
104            })
105            .collect();
106        Ok(result)
107    }
108    
109    /// Async count by keypath predicate
110    pub async fn count_by_keypath_async<T, V, F>(
111        collection: Vec<T>,
112        keypath: KeyPaths<T, V>,
113        predicate: F,
114    ) -> KeyPathResult<usize>
115    where
116        T: Send + Sync + KeyPathsOperable,
117        V: Send + Sync,
118        KeyPaths<T, V>: Send + Sync,
119        F: Fn(&V) -> bool + Send + Sync + 'static,
120    {
121        let count = collection
122            .into_iter()
123            .filter(|item| {
124                let value = item.get_at_keypath(&keypath).unwrap_or_else(|_| {
125                    panic!("KeyPath access failed in count_by_keypath_async")
126                });
127                predicate(value)
128            })
129            .count();
130        Ok(count)
131    }
132    
133    /// Async any by keypath predicate
134    pub async fn any_by_keypath_async<T, V, F>(
135        collection: Vec<T>,
136        keypath: KeyPaths<T, V>,
137        predicate: F,
138    ) -> KeyPathResult<bool>
139    where
140        T: Send + Sync + KeyPathsOperable,
141        V: Send + Sync,
142        KeyPaths<T, V>: Send + Sync,
143        F: Fn(&V) -> bool + Send + Sync + 'static,
144    {
145        let result = collection
146            .into_iter()
147            .any(|item| {
148                let value = item.get_at_keypath(&keypath).unwrap_or_else(|_| {
149                    panic!("KeyPath access failed in any_by_keypath_async")
150                });
151                predicate(value)
152            });
153        Ok(result)
154    }
155    
156    /// Async all by keypath predicate
157    pub async fn all_by_keypath_async<T, V, F>(
158        collection: Vec<T>,
159        keypath: KeyPaths<T, V>,
160        predicate: F,
161    ) -> KeyPathResult<bool>
162    where
163        T: Send + Sync + KeyPathsOperable,
164        V: Send + Sync,
165        KeyPaths<T, V>: Send + Sync,
166        F: Fn(&V) -> bool + Send + Sync + 'static,
167    {
168        let result = collection
169            .into_iter()
170            .all(|item| {
171                let value = item.get_at_keypath(&keypath).unwrap_or_else(|_| {
172                    panic!("KeyPath access failed in all_by_keypath_async")
173                });
174                predicate(value)
175            });
176        Ok(result)
177    }
178}
179
180#[cfg(all(feature = "async", feature = "serde"))]
181/// Async operations with JSON serialization/deserialization
182pub mod async_json {
183    use super::*;
184    use serde::{Deserialize, Serialize};
185    
186    /// Read and process JSON data with keypath
187    pub async fn read_and_process_keypath<T, V, F, R>(
188        json_data: &str,
189        keypath: KeyPaths<T, V>,
190        processor: F,
191    ) -> KeyPathResult<Vec<R>>
192    where
193        T: Deserialize + Send + Sync + KeyPathsOperable,
194        V: Send + Sync,
195        KeyPaths<T, V>: Send + Sync,
196        F: Fn(&V) -> R + Send + Sync + 'static,
197        R: Send,
198    {
199        let data: Vec<T> = serde_json::from_str(json_data)
200            .map_err(|e| KeyPathError::SerializationError {
201                message: format!("Failed to deserialize JSON: {}", e),
202            })?;
203        
204        async_collections::map_keypath_async(data, keypath, processor).await
205    }
206    
207    /// Process data and write as JSON with keypath
208    pub async fn process_and_write_keypath<T, V, F, R>(
209        collection: Vec<T>,
210        keypath: KeyPaths<T, V>,
211        processor: F,
212    ) -> KeyPathResult<String>
213    where
214        T: Send + Sync + KeyPathsOperable,
215        V: Send + Sync,
216        KeyPaths<T, V>: Send + Sync,
217        F: Fn(&V) -> R + Send + Sync + 'static,
218        R: Send + Serialize,
219    {
220        let results = async_collections::map_keypath_async(collection, keypath, processor).await?;
221        
222        let json = serde_json::to_string(&results)
223            .map_err(|e| KeyPathError::SerializationError {
224                message: format!("Failed to serialize to JSON: {}", e),
225            })?;
226        
227        Ok(json)
228    }
229}
230
231#[cfg(feature = "async")]
232/// Async operations with HTTP requests
233pub mod async_http {
234    use super::*;
235    
236    /// Fetch data from URL and process with keypath
237    pub async fn fetch_and_process_keypath<T, V, F, R>(
238        url: &str,
239        keypath: KeyPaths<T, V>,
240        processor: F,
241    ) -> KeyPathResult<Vec<R>>
242    where
243        T: serde::de::DeserializeOwned + Send + Sync + KeyPathsOperable,
244        V: Send + Sync,
245        KeyPaths<T, V>: Send + Sync,
246        F: Fn(&V) -> R + Send + Sync + 'static,
247        R: Send,
248    {
249        let response = reqwest::get(url).await
250            .map_err(|e| KeyPathError::NetworkError {
251                message: format!("Failed to fetch data: {}", e),
252            })?;
253        
254        let data: Vec<T> = response.json().await
255            .map_err(|e| KeyPathError::SerializationError {
256                message: format!("Failed to deserialize response: {}", e),
257            })?;
258        
259        async_collections::map_keypath_async(data, keypath, processor).await
260    }
261    
262    /// Process data and send HTTP POST request
263    pub async fn process_and_send_keypath<T, V, F, R>(
264        collection: Vec<T>,
265        keypath: KeyPaths<T, V>,
266        processor: F,
267        url: &str,
268    ) -> KeyPathResult<reqwest::Response>
269    where
270        T: Send + Sync + KeyPathsOperable,
271        V: Send + Sync,
272        KeyPaths<T, V>: Send + Sync,
273        F: Fn(&V) -> R + Send + Sync + 'static,
274        R: Send + serde::Serialize,
275    {
276        let results = async_collections::map_keypath_async(collection, keypath, processor).await?;
277        
278        let client = reqwest::Client::new();
279        let response = client.post(url)
280            .json(&results)
281            .send()
282            .await
283            .map_err(|e| KeyPathError::NetworkError {
284                message: format!("Failed to send data: {}", e),
285            })?;
286        
287        Ok(response)
288    }
289}