2025-08-14 06:10:52 +00:00
|
|
|
/*! 🌐 HTTP Method Implementations
|
|
|
|
|
*
|
|
|
|
|
* HTTP関連Boxのメソッド実行を実装
|
|
|
|
|
* SocketBox, HTTPServerBox, HTTPRequestBox, HTTPResponseBox
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
use super::super::*;
|
|
|
|
|
use crate::boxes::{SocketBox, HTTPServerBox, HTTPRequestBox, HTTPResponseBox};
|
|
|
|
|
|
|
|
|
|
impl NyashInterpreter {
|
|
|
|
|
/// SocketBox methods
|
|
|
|
|
pub(in crate::interpreter) fn execute_socket_method(
|
|
|
|
|
&mut self,
|
|
|
|
|
socket_box: &SocketBox,
|
|
|
|
|
method: &str,
|
|
|
|
|
arguments: &[ASTNode]
|
|
|
|
|
) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
|
|
|
|
match method {
|
|
|
|
|
"bind" => {
|
|
|
|
|
if arguments.len() != 2 {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("bind() expects 2 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let address = self.execute_expression(&arguments[0])?;
|
|
|
|
|
let port = self.execute_expression(&arguments[1])?;
|
2025-08-14 20:55:33 +09:00
|
|
|
let result = socket_box.bind(address, port);
|
|
|
|
|
Ok(result)
|
2025-08-14 06:10:52 +00:00
|
|
|
}
|
|
|
|
|
"listen" => {
|
|
|
|
|
if arguments.len() != 1 {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("listen() expects 1 argument, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let backlog = self.execute_expression(&arguments[0])?;
|
|
|
|
|
Ok(socket_box.listen(backlog))
|
|
|
|
|
}
|
|
|
|
|
"accept" => {
|
|
|
|
|
if !arguments.is_empty() {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("accept() expects 0 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(socket_box.accept())
|
|
|
|
|
}
|
2025-08-23 21:13:02 +09:00
|
|
|
"acceptTimeout" | "accept_timeout" => {
|
|
|
|
|
if arguments.len() != 1 {
|
|
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("acceptTimeout(ms) expects 1 argument, got {}", arguments.len()),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
let ms = self.execute_expression(&arguments[0])?;
|
|
|
|
|
Ok(socket_box.accept_timeout(ms))
|
|
|
|
|
}
|
2025-08-14 06:10:52 +00:00
|
|
|
"connect" => {
|
|
|
|
|
if arguments.len() != 2 {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("connect() expects 2 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let address = self.execute_expression(&arguments[0])?;
|
|
|
|
|
let port = self.execute_expression(&arguments[1])?;
|
|
|
|
|
Ok(socket_box.connect(address, port))
|
|
|
|
|
}
|
|
|
|
|
"read" => {
|
|
|
|
|
if !arguments.is_empty() {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("read() expects 0 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(socket_box.read())
|
|
|
|
|
}
|
2025-08-23 21:13:02 +09:00
|
|
|
"recvTimeout" | "recv_timeout" => {
|
|
|
|
|
if arguments.len() != 1 {
|
|
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("recvTimeout(ms) expects 1 argument, got {}", arguments.len()),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
let ms = self.execute_expression(&arguments[0])?;
|
|
|
|
|
Ok(socket_box.recv_timeout(ms))
|
|
|
|
|
}
|
2025-08-14 06:10:52 +00:00
|
|
|
"readHttpRequest" => {
|
|
|
|
|
if !arguments.is_empty() {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("readHttpRequest() expects 0 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(socket_box.read_http_request())
|
|
|
|
|
}
|
|
|
|
|
"write" => {
|
|
|
|
|
if arguments.len() != 1 {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("write() expects 1 argument, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let data = self.execute_expression(&arguments[0])?;
|
|
|
|
|
Ok(socket_box.write(data))
|
|
|
|
|
}
|
|
|
|
|
"close" => {
|
|
|
|
|
if !arguments.is_empty() {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("close() expects 0 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(socket_box.close())
|
|
|
|
|
}
|
|
|
|
|
"isConnected" => {
|
|
|
|
|
if !arguments.is_empty() {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("isConnected() expects 0 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(socket_box.is_connected())
|
|
|
|
|
}
|
|
|
|
|
"isServer" => {
|
|
|
|
|
if !arguments.is_empty() {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("isServer() expects 0 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(socket_box.is_server())
|
|
|
|
|
}
|
2025-08-14 06:20:45 +00:00
|
|
|
"toString" => {
|
|
|
|
|
if !arguments.is_empty() {
|
|
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("toString() expects 0 arguments, got {}", arguments.len()),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(Box::new(socket_box.to_string_box()))
|
|
|
|
|
}
|
|
|
|
|
_ => Err(RuntimeError::UndefinedVariable {
|
|
|
|
|
name: format!("SocketBox method '{}' not found", method),
|
2025-08-14 06:10:52 +00:00
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// HTTPServerBox methods
|
|
|
|
|
pub(in crate::interpreter) fn execute_http_server_method(
|
|
|
|
|
&mut self,
|
|
|
|
|
server_box: &HTTPServerBox,
|
|
|
|
|
method: &str,
|
|
|
|
|
arguments: &[ASTNode]
|
|
|
|
|
) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
|
|
|
|
match method {
|
|
|
|
|
"bind" => {
|
|
|
|
|
if arguments.len() != 2 {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("bind() expects 2 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let address = self.execute_expression(&arguments[0])?;
|
|
|
|
|
let port = self.execute_expression(&arguments[1])?;
|
|
|
|
|
Ok(server_box.bind(address, port))
|
|
|
|
|
}
|
|
|
|
|
"listen" => {
|
|
|
|
|
if arguments.len() != 1 {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("listen() expects 1 argument, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let backlog = self.execute_expression(&arguments[0])?;
|
|
|
|
|
Ok(server_box.listen(backlog))
|
|
|
|
|
}
|
|
|
|
|
"start" => {
|
|
|
|
|
if !arguments.is_empty() {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("start() expects 0 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(server_box.start())
|
|
|
|
|
}
|
|
|
|
|
"stop" => {
|
|
|
|
|
if !arguments.is_empty() {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("stop() expects 0 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(server_box.stop())
|
|
|
|
|
}
|
|
|
|
|
"get" => {
|
|
|
|
|
if arguments.len() != 2 {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("get() expects 2 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let path = self.execute_expression(&arguments[0])?;
|
|
|
|
|
let handler = self.execute_expression(&arguments[1])?;
|
|
|
|
|
Ok(server_box.get(path, handler))
|
|
|
|
|
}
|
2025-08-14 06:20:45 +00:00
|
|
|
"toString" => {
|
2025-08-14 06:10:52 +00:00
|
|
|
if !arguments.is_empty() {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("toString() expects 0 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-14 06:20:45 +00:00
|
|
|
Ok(Box::new(server_box.to_string_box()))
|
2025-08-14 06:10:52 +00:00
|
|
|
}
|
2025-08-14 06:20:45 +00:00
|
|
|
_ => Err(RuntimeError::UndefinedVariable {
|
|
|
|
|
name: format!("HTTPServerBox method '{}' not found", method),
|
2025-08-14 06:10:52 +00:00
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-14 06:20:45 +00:00
|
|
|
/// HTTPRequestBox methods
|
2025-08-14 06:10:52 +00:00
|
|
|
pub(in crate::interpreter) fn execute_http_request_method(
|
|
|
|
|
&mut self,
|
|
|
|
|
request_box: &HTTPRequestBox,
|
|
|
|
|
method: &str,
|
|
|
|
|
arguments: &[ASTNode]
|
|
|
|
|
) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
|
|
|
|
match method {
|
|
|
|
|
"getMethod" => {
|
|
|
|
|
if !arguments.is_empty() {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("getMethod() expects 0 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(request_box.get_method())
|
|
|
|
|
}
|
|
|
|
|
"getPath" => {
|
|
|
|
|
if !arguments.is_empty() {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("getPath() expects 0 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(request_box.get_path())
|
|
|
|
|
}
|
2025-08-14 06:20:45 +00:00
|
|
|
"toString" => {
|
2025-08-14 06:10:52 +00:00
|
|
|
if !arguments.is_empty() {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("toString() expects 0 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-14 06:20:45 +00:00
|
|
|
Ok(Box::new(request_box.to_string_box()))
|
2025-08-14 06:10:52 +00:00
|
|
|
}
|
2025-08-14 06:20:45 +00:00
|
|
|
_ => Err(RuntimeError::UndefinedVariable {
|
|
|
|
|
name: format!("HTTPRequestBox method '{}' not found", method),
|
2025-08-14 06:10:52 +00:00
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// HTTPResponseBox methods
|
|
|
|
|
pub(in crate::interpreter) fn execute_http_response_method(
|
|
|
|
|
&mut self,
|
|
|
|
|
response_box: &HTTPResponseBox,
|
|
|
|
|
method: &str,
|
|
|
|
|
arguments: &[ASTNode]
|
|
|
|
|
) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
|
|
|
|
match method {
|
|
|
|
|
"setStatus" => {
|
|
|
|
|
if arguments.len() != 2 {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("setStatus() expects 2 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let code = self.execute_expression(&arguments[0])?;
|
|
|
|
|
let message = self.execute_expression(&arguments[1])?;
|
|
|
|
|
Ok(response_box.set_status(code, message))
|
|
|
|
|
}
|
2025-08-14 06:20:45 +00:00
|
|
|
"toHttpString" => {
|
|
|
|
|
if !arguments.is_empty() {
|
|
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("toHttpString() expects 0 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-14 06:20:45 +00:00
|
|
|
Ok(response_box.to_http_string())
|
2025-08-14 06:10:52 +00:00
|
|
|
}
|
2025-08-14 06:20:45 +00:00
|
|
|
"toString" => {
|
2025-08-14 06:10:52 +00:00
|
|
|
if !arguments.is_empty() {
|
2025-08-14 06:20:45 +00:00
|
|
|
return Err(RuntimeError::InvalidOperation {
|
|
|
|
|
message: format!("toString() expects 0 arguments, got {}", arguments.len()),
|
2025-08-14 06:10:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-14 06:20:45 +00:00
|
|
|
Ok(Box::new(response_box.to_string_box()))
|
2025-08-14 06:10:52 +00:00
|
|
|
}
|
2025-08-14 06:20:45 +00:00
|
|
|
_ => Err(RuntimeError::UndefinedVariable {
|
|
|
|
|
name: format!("HTTPResponseBox method '{}' not found", method),
|
2025-08-14 06:10:52 +00:00
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-08-23 21:13:02 +09:00
|
|
|
}
|