Skip to content

Commit 77c1abb

Browse files
authored
Merge pull request #6 from Na-x4/feature/update-messages
Feature/update messages
2 parents 52c19b9 + c85374a commit 77c1abb

5 files changed

Lines changed: 244 additions & 87 deletions

File tree

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ base64 = "0.13"
1212
encoding_rs = "0.8"
1313
getopts = "0.2.21"
1414
libloading = "0.7"
15+
optional_take = "0.1.0"
1516
serde = { version = "1.0", features = ["derive"] }
1617
serde_json = "1.0"
1718
threadpool = "1.8"

src/server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
// along with AquesTalk-proxy. If not, see <https://www.gnu.org/licenses/>.
1717

1818
mod connection;
19-
pub mod messages;
19+
mod messages;
2020

2121
use std::collections::HashMap;
2222
use std::net::{TcpListener, TcpStream, ToSocketAddrs};

src/server/connection.rs

Lines changed: 173 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,40 @@
11
use std::collections::HashMap;
22
use std::io::{Read, Write};
33

4-
use serde_json::Deserializer;
4+
use optional_take::io::Takable;
5+
use serde_json::{Deserializer, Value};
56

67
use crate::aquestalk::AquesTalk;
78

8-
use super::messages::{Req, Res};
9+
use super::messages::{
10+
Request, Response, ResponsePayload,
11+
ResponseStatus::{self, *},
12+
};
13+
14+
pub fn new_voice_type_error(voice_type: String) -> ResponsePayload {
15+
ResponsePayload::AquestalkError {
16+
code: None,
17+
message: format!("不明な声種 ({})", voice_type),
18+
}
19+
}
20+
21+
pub fn new_limit_reached_error() -> ResponsePayload {
22+
ResponsePayload::ConnectionError {
23+
message: "Request is too long".to_string(),
24+
}
25+
}
26+
27+
fn write_response<W>(
28+
writer: &mut W,
29+
status: ResponseStatus,
30+
payload: ResponsePayload,
31+
request: Option<Value>,
32+
) -> serde_json::Result<()>
33+
where
34+
W: Write,
35+
{
36+
serde_json::to_writer(writer, &Response::new(status, payload, request))
37+
}
938

1039
pub fn handle_connection<R, W>(
1140
reader: R,
@@ -17,33 +46,54 @@ where
1746
R: Read,
1847
W: Write,
1948
{
20-
let reader: Box<dyn Read> = match limit {
21-
Some(limit) => Box::new(reader.take(limit)),
22-
None => Box::new(reader),
23-
};
24-
let reader = Deserializer::from_reader(reader).into_iter::<Req>();
25-
26-
for req in reader {
27-
let req = match req {
28-
Ok(req) => req,
29-
Err(ref err) => {
30-
serde_json::to_writer(&mut writer, &Res::from_error(err))?;
49+
let mut reader = reader.take_optional(limit);
50+
51+
let deserializer = Deserializer::from_reader(&mut reader).into_iter::<Value>();
52+
for request in deserializer {
53+
let request = match request {
54+
Ok(request) => request,
55+
Err(err) => {
56+
let payload = if err.is_eof() && reader.limit() == Some(0) {
57+
new_limit_reached_error()
58+
} else {
59+
ResponsePayload::from(err)
60+
};
61+
62+
write_response(&mut writer, Failure, payload, None)?;
3163
break;
3264
}
3365
};
34-
let aq = match aqtks.get(&req.voice_type) {
66+
67+
let write_response = {
68+
let request = request.clone();
69+
|status, payload| write_response(&mut writer, status, payload, Some(request))
70+
};
71+
72+
let request: Request = match serde_json::from_value(request) {
73+
Ok(request) => request,
74+
Err(err) => {
75+
write_response(Reusable, ResponsePayload::from(err))?;
76+
continue;
77+
}
78+
};
79+
80+
let aq = match aqtks.get(&request.voice_type) {
3581
Some(aq) => aq,
3682
None => {
37-
serde_json::to_writer(
38-
&mut writer,
39-
&Res::from_error_message(&format!("不明な声質 ({})", req.voice_type)),
40-
)?;
83+
write_response(Reusable, new_voice_type_error(request.voice_type))?;
84+
continue;
85+
}
86+
};
87+
88+
let wav = match aq.synthe(&request.koe, request.speed) {
89+
Ok(wav) => wav,
90+
Err(err) => {
91+
write_response(Reusable, ResponsePayload::from(err))?;
4192
continue;
4293
}
4394
};
44-
let wav = aq.synthe(&req.koe, req.speed);
4595

46-
serde_json::to_writer(&mut writer, &Res::from(wav))?;
96+
write_response(Success, ResponsePayload::from(wav))?;
4797
}
4898

4999
writer.flush()?;
@@ -52,8 +102,10 @@ where
52102

53103
#[cfg(test)]
54104
mod test {
105+
use serde_json::{json, Value};
106+
55107
use super::handle_connection;
56-
use crate::{aquestalk::load_libs, server::messages::Res};
108+
use crate::aquestalk::load_libs;
57109

58110
#[test]
59111
fn test_connection() {
@@ -62,12 +114,23 @@ mod test {
62114
let mut output = Vec::new();
63115

64116
handle_connection(input, &mut output, libs, None).unwrap();
65-
let output: Res = serde_json::from_str(&String::from_utf8(output).unwrap()).unwrap();
117+
let mut response: Value =
118+
serde_json::from_str(&String::from_utf8(output).unwrap()).unwrap();
119+
if response["response"]["wav"].is_string() {
120+
response["response"]["wav"] = json!("===WAV DATA===");
121+
}
66122

67-
match output {
68-
Res::Success { wav: _ } => (),
69-
_ => unreachable!(),
70-
};
123+
assert_eq!(
124+
response,
125+
json!(
126+
{
127+
"isSuccess": true,
128+
"isConnectionReusable": true,
129+
"response": { "type": "Wav", "wav": "===WAV DATA===" },
130+
"request": { "koe": "こんにちわ、せ'かい" }
131+
}
132+
)
133+
);
71134
}
72135

73136
#[test]
@@ -77,15 +140,21 @@ mod test {
77140
let mut output = Vec::new();
78141

79142
handle_connection(input, &mut output, libs, Some(37)).unwrap();
80-
let output: Res = serde_json::from_str(&String::from_utf8(output).unwrap()).unwrap();
143+
let response: Value = serde_json::from_str(&String::from_utf8(output).unwrap()).unwrap();
81144

82-
match output {
83-
Res::Error { ref message, code } => {
84-
assert_eq!(code, None);
85-
assert_eq!(message, "EOF while parsing an object at line 1 column 37");
86-
}
87-
_ => unreachable!(),
88-
};
145+
assert_eq!(
146+
response,
147+
json!(
148+
{
149+
"isSuccess": false,
150+
"isConnectionReusable": false,
151+
"response": {
152+
"type": "ConnectionError",
153+
"message": "Request is too long"
154+
}
155+
}
156+
)
157+
);
89158
}
90159

91160
#[test]
@@ -95,15 +164,46 @@ mod test {
95164
let mut output = Vec::new();
96165

97166
handle_connection(input, &mut output, libs, None).unwrap();
98-
let output: Res = serde_json::from_str(&String::from_utf8(output).unwrap()).unwrap();
167+
let response: Value = serde_json::from_str(&String::from_utf8(output).unwrap()).unwrap();
99168

100-
match output {
101-
Res::Error { ref message, code } => {
102-
assert_eq!(code, None);
103-
assert_eq!(message, "EOF while parsing an object at line 1 column 37");
104-
}
105-
_ => unreachable!(),
106-
};
169+
assert_eq!(
170+
response,
171+
json!(
172+
{
173+
"isConnectionReusable": false,
174+
"isSuccess": false,
175+
"response": {
176+
"type": "JsonError",
177+
"message": "EOF while parsing an object at line 1 column 37"
178+
}
179+
}
180+
)
181+
);
182+
}
183+
184+
#[test]
185+
fn test_json_error_reusable() {
186+
let libs = load_libs(&"./aquestalk").unwrap();
187+
let input = "{\"koee\":\"こんにちわ、せ'かい\"}".as_bytes();
188+
let mut output = Vec::new();
189+
190+
handle_connection(input, &mut output, libs, None).unwrap();
191+
let response: Value = serde_json::from_str(&String::from_utf8(output).unwrap()).unwrap();
192+
193+
assert_eq!(
194+
response,
195+
json!(
196+
{
197+
"isConnectionReusable": true,
198+
"isSuccess": false,
199+
"response": {
200+
"type": "JsonError",
201+
"message": "unknown field `koee`, expected one of `type`, `speed`, `koe`"
202+
},
203+
"request": { "koee": "こんにちわ、せ'かい" }
204+
}
205+
)
206+
);
107207
}
108208

109209
#[test]
@@ -113,15 +213,22 @@ mod test {
113213
let mut output = Vec::new();
114214

115215
handle_connection(input, &mut output, libs, None).unwrap();
116-
let output: Res = serde_json::from_str(&String::from_utf8(output).unwrap()).unwrap();
216+
let response: Value = serde_json::from_str(&String::from_utf8(output).unwrap()).unwrap();
117217

118-
match output {
119-
Res::Error { ref message, code } => {
120-
assert_eq!(code, None);
121-
assert_eq!(message, "不明な声質 (invalid type)");
122-
}
123-
_ => unreachable!(),
124-
};
218+
assert_eq!(
219+
response,
220+
json!(
221+
{
222+
"isConnectionReusable": true,
223+
"isSuccess": false,
224+
"response": {
225+
"type": "AquestalkError",
226+
"message": "不明な声種 (invalid type)"
227+
},
228+
"request": { "type": "invalid type", "koe": "こんにちわ、せ'かい" }
229+
}
230+
)
231+
);
125232
}
126233

127234
#[test]
@@ -131,14 +238,22 @@ mod test {
131238
let mut output = Vec::new();
132239

133240
handle_connection(input, &mut output, libs, None).unwrap();
134-
let output: Res = serde_json::from_str(&String::from_utf8(output).unwrap()).unwrap();
241+
let response: Value = serde_json::from_str(&String::from_utf8(output).unwrap()).unwrap();
135242

136-
match output {
137-
Res::Error { ref message, code } => {
138-
assert_eq!(code, Some(105));
139-
assert_eq!(message, "音声記号列に未定義の読み記号が指定された");
140-
}
141-
_ => unreachable!(),
142-
};
243+
assert_eq!(
244+
response,
245+
json!(
246+
{
247+
"isConnectionReusable": true,
248+
"isSuccess": false,
249+
"response": {
250+
"type": "AquestalkError",
251+
"code": 105,
252+
"message": "音声記号列に未定義の読み記号が指定された"
253+
},
254+
"request": { "koe": "🤔" }
255+
}
256+
)
257+
);
143258
}
144259
}

0 commit comments

Comments
 (0)