1use std::collections::HashMap;
2use std::fmt::Write;
3
4use serde::{Deserialize, Serialize};
5
6use crate::{WWSVCError, params::Parameters};
7
8pub trait RequestToHttpString {
10 fn to_http_string(&self) -> Result<String, WWSVCError>;
12}
13
14impl RequestToHttpString for reqwest::Request {
15 fn to_http_string(&self) -> Result<String, WWSVCError> {
16 let mut result = String::new();
17
18 writeln!(
19 result,
20 "{} {}{} HTTP/1.1",
21 self.method(),
22 self.url().path(),
23 self.url().query().unwrap_or("")
24 )?;
25
26 if let Some(host) = self.url().host_str() {
27 if let Some(port) = self.url().port() {
28 writeln!(result, "host: {}:{}", host, port)?;
29 } else {
30 writeln!(result, "host: {}", host)?;
31 }
32 }
33
34 for (name, value) in self.headers() {
35 writeln!(result, "{}: {}", name, value.to_str()?)?;
36 }
37
38 writeln!(result)?;
39
40 if let Some(body) = self.body() {
41 if let Some(bytes) = body.as_bytes() {
42 result.push_str(&String::from_utf8_lossy(bytes));
43 } else {
44 result.push_str("[streaming body - cannot display]");
45 }
46 }
47
48 Ok(result)
49 }
50}
51
52#[derive(Serialize, Deserialize, Clone, Debug)]
54pub struct ExecJsonRequest {
55 #[serde(rename = "WWSVC_FUNCTION")]
57 pub function: ServiceFunction,
58 #[serde(rename = "WWSVC_PASSINFO")]
60 pub pass_info: ServicePassInfo,
61}
62
63impl ExecJsonRequest {
64 pub fn new(
66 function_name: &str,
67 parameters: Vec<ServiceFunctionParameter>,
68 version: u32,
69 service_pass: &str,
70 app_hash: &str,
71 timestamp: &str,
72 request_id: u32,
73 ) -> Self {
74 Self {
75 function: ServiceFunction {
76 function_name: function_name.to_string(),
77 parameters,
78 revision: version,
79 },
80 pass_info: ServicePassInfo {
81 service_pass: service_pass.to_string(),
82 app_hash: app_hash.to_string(),
83 timestamp: timestamp.to_string(),
84 request_id,
85 execute_mode: "SYNCHRON".to_string(),
86 },
87 }
88 }
89}
90
91#[derive(Serialize, Deserialize, Clone, Debug)]
93pub struct ServiceFunction {
94 #[serde(rename = "FUNCTIONNAME")]
96 pub function_name: String,
97 #[serde(rename = "PARAMETER")]
99 pub parameters: Vec<ServiceFunctionParameter>,
100 #[serde(rename = "REVISION")]
102 pub revision: u32,
103}
104
105#[derive(Serialize, Deserialize, Clone, Debug)]
107pub struct ServiceFunctionParameter {
108 #[serde(rename = "PNAME")]
110 pub name: String,
111 #[serde(rename = "PCONTENT")]
113 pub content: String,
114}
115
116pub trait ToServiceFunctionParameters {
118 fn to_service_function_parameters(&self) -> Vec<ServiceFunctionParameter>;
120}
121
122impl ToServiceFunctionParameters for HashMap<String, String> {
123 fn to_service_function_parameters(&self) -> Vec<ServiceFunctionParameter> {
125 self.iter()
126 .map(|(name, content)| ServiceFunctionParameter {
127 name: name.clone(),
128 content: content.clone(),
129 })
130 .collect()
131 }
132}
133
134impl ToServiceFunctionParameters for HashMap<&str, &str> {
135 fn to_service_function_parameters(&self) -> Vec<ServiceFunctionParameter> {
137 self.iter()
138 .map(|(name, content)| ServiceFunctionParameter {
139 name: name.to_string(),
140 content: content.to_string(),
141 })
142 .collect()
143 }
144}
145
146impl ToServiceFunctionParameters for Parameters {
147 fn to_service_function_parameters(&self) -> Vec<ServiceFunctionParameter> {
149 self.as_inner().iter()
150 .map(|(name, content): (&String, &String)| ServiceFunctionParameter {
151 name: name.clone(),
152 content: content.clone(),
153 })
154 .collect()
155 }
156}
157
158#[derive(Serialize, Deserialize, Clone, Debug)]
160pub struct ServicePassInfo {
161 #[serde(rename = "SERVICEPASS")]
163 pub service_pass: String,
164 #[serde(rename = "APPHASH")]
166 pub app_hash: String,
167 #[serde(rename = "TIMESTAMP")]
169 pub timestamp: String,
170 #[serde(rename = "REQUESTID")]
172 pub request_id: u32,
173 #[serde(rename = "EXECUTE_MODE")]
175 pub execute_mode: String,
176}