awpak_rs/parser/
parser.rs1use std::collections::HashMap;
2
3use serde_json::Value;
4
5use crate::{from_async_str::FromAsyncStr, from_value::FromValue, io::io::IO};
6
7pub fn serialize_value<T>( value : T ) -> Option<Value>
8where T: serde::Serialize
9{
10 match serde_json::to_value( value ) {
11 Ok( v ) => Some( v ),
12 _ => None
13 }
14}
15
16pub fn parse_value<T>( io : &IO, from : &str ) -> Option<T>
17where T: for<'a> serde::Deserialize<'a> + FromValue
18{
19 match from
20 {
21 "request_body" => parse_value_from_request_body( io ),
22 "query_params" => parse_value_from_query_params( io ),
23 _ => None
24 }
25}
26
27pub fn parse_body_param_value<T>( io : &IO, name : &str ) -> Option<T>
28where T: for<'a> serde::Deserialize<'a> + FromValue
29{
30 match io.request.body.get_param( name ) {
31 Some( v ) => T::from_value( v ),
32 _ => None
33 }
34}
35
36pub fn parse_from_value<T>( value : &Value ) -> Option<T>
37where T: for<'a> serde::Deserialize<'a>
38{
39 match serde_json::from_value( value.clone() )
40 {
41 Ok( v ) => Some( v ),
42 _ => match value {
43 serde_json::Value::String( v ) => match serde_json::from_str( v )
44 {
45 Ok( v ) => Some( v ),
46 _ => None
47 },
48 _ => None
49 }
50 }
51}
52
53fn parse_value_from_request_body<T>( io : &IO ) -> Option<T>
54where T: for<'a> serde::Deserialize<'a> + FromValue
55{
56 match io.request.body.value.as_ref()
57 {
58 Some( v ) => T::from_value( v ),
59 _ => None
60 }
61}
62
63pub fn parse_query_param_value<T>( io : &IO, name : &str ) -> Option<T>
64where T: for<'a> serde::Deserialize<'a> + FromValue
65{
66 match &io.request.uri.query_map
67 {
68 Some( v ) => match v.get( name )
69 {
70 Some( s ) => match &serde_json::from_str( s )
71 {
72 Ok( v ) => T::from_value( v ),
73 _ => match serde_json::to_value( s )
74 {
75 Ok( v ) => T::from_value( &v ),
76 _ => None
77 }
78 },
79 _ => T::from_value( &serde_json::Value::Null )
80 },
81 _ => T::from_value( &serde_json::Value::Null )
82 }
83}
84
85fn parse_value_from_query_params<T>( io : &IO ) -> Option<T>
86where T: for<'a> serde::Deserialize<'a>
87{
88 let query_params = &io.request.uri.query;
89
90 if query_params.is_none()
91 {
92 let salida : Result<T, _> = serde_qs::from_str( "" );
93
94 if salida.is_err()
95 {
96 return None;
97 }
98
99 return Some( salida.unwrap() );
100 }
101
102 let salida : Result<T, _> = serde_qs::from_str( query_params.as_ref().unwrap() );
103
104 if salida.is_err()
105 {
106 if io.request.uri.query_map.is_none()
108 {
109 return None;
110 }
111
112 let mut map : HashMap<String, serde_json::Value> = HashMap::new();
113
114 for item in io.request.uri.query_map.as_ref().unwrap()
115 {
116 let val = match serde_json::from_str::<serde_json::Value>( item.1 )
117 {
118 Ok( v ) => Ok( v ),
119 _ => match serde_json::to_value( item.1 ) {
120 Ok( v ) => Ok( v ),
121 _ => Err( () )
122 }
123 };
124
125 if val.is_ok()
126 {
127 map.insert( item.0.clone(), val.unwrap() );
128 }
129 }
130
131 let value = serde_json::to_value( map );
132
133 if value.is_err()
134 {
135 return None;
136 }
137
138 let salida : Result<T, _> = serde_json::from_value( value.unwrap() );
139
140 if salida.is_err()
141 {
142 return None;
143 }
144
145 return Some( salida.unwrap() )
146 }
147
148 Some( salida.unwrap() )
149}
150
151pub async fn parse_path_variable<T>( io : &IO, ind : usize ) -> Option<T>
152where T: FromAsyncStr<T>
153{
154 match io.request.uri.path.split( "/" ).enumerate().find( | v | v.0 == ind ).map( | v | v.1 )
155 {
156 Some( v ) => match T::from_async_str( io, v ).await
157 {
158 Ok( v ) => Some( v ),
159 _ => None
160 },
161 _ => None
162 }
163}
164
165#[cfg(test)]
166mod tests {
167 use crate::io::response::response_data::ResponseData;
168
169 use super::*;
170
171 #[test]
172 fn test_parse_query_param_value()
173 {
174 let io = IO::with_response( ResponseData::default() );
175
176 let val = parse_query_param_value::<Option<String>>( &io, "a" );
177
178 assert!( val.is_some() );
179
180 let val = val.unwrap();
181
182 assert!( val.is_none() );
183 }
184}