1use eyre::{eyre, Result};
36use std::net::{SocketAddr, TcpListener};
37use tracing::{debug, info};
38
39pub fn find_available_port(start_port: u16) -> Result<u16> {
41 for port in start_port..65535 {
42 if is_port_available(port) {
43 info!("Found available port: {}", port);
44 return Ok(port);
45 }
46 }
47 Err(eyre!("No available port found in range {}-65534", start_port))
48}
49
50pub fn is_port_available(port: u16) -> bool {
52 match TcpListener::bind(("127.0.0.1", port)) {
53 Ok(_) => {
54 debug!("Port {} is available", port);
55 true
56 }
57 Err(_) => {
58 debug!("Port {} is not available", port);
59 false
60 }
61 }
62}
63
64pub fn get_default_rpc_port() -> Result<u16> {
66 if is_port_available(3000) {
67 Ok(3000)
68 } else {
69 find_available_port(3001)
70 }
71}
72
73pub fn parse_socket_addr(addr_str: Option<&str>, default_port: u16) -> Result<SocketAddr> {
75 match addr_str {
76 Some(addr) => addr.parse().map_err(|e| eyre!("Invalid socket address '{}': {}", addr, e)),
77 None => Ok(SocketAddr::from(([127, 0, 0, 1], default_port))),
78 }
79}
80
81pub fn to_rpc_error(
83 code: i32,
84 message: &str,
85 data: Option<serde_json::Value>,
86) -> crate::rpc::types::RpcError {
87 crate::rpc::types::RpcError { code, message: message.to_string(), data }
88}
89
90pub fn internal_error(message: &str) -> crate::rpc::types::RpcError {
92 to_rpc_error(crate::rpc::types::error_codes::INTERNAL_ERROR, message, None)
93}
94
95pub fn method_not_found(method: &str) -> crate::rpc::types::RpcError {
97 to_rpc_error(
98 crate::rpc::types::error_codes::METHOD_NOT_FOUND,
99 &format!("Method '{method}' not found"),
100 None,
101 )
102}
103
104pub fn invalid_params(message: &str) -> crate::rpc::types::RpcError {
106 to_rpc_error(crate::rpc::types::error_codes::INVALID_PARAMS, message, None)
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112
113 #[test]
114 fn test_port_availability() {
115 let port = find_available_port(50000).expect("Should find an available port");
117 assert!(port >= 50000);
118 assert!(is_port_available(port));
119 }
120
121 #[test]
122 fn test_socket_addr_parsing() {
123 let addr = parse_socket_addr(Some("127.0.0.1:8080"), 3000).unwrap();
124 assert_eq!(addr.port(), 8080);
125
126 let addr = parse_socket_addr(None, 3000).unwrap();
127 assert_eq!(addr.port(), 3000);
128 assert_eq!(addr.ip().to_string(), "127.0.0.1");
129 }
130
131 #[test]
132 fn test_error_helpers() {
133 let err = internal_error("test message");
134 assert_eq!(err.code, -32603);
135 assert_eq!(err.message, "test message");
136
137 let err = method_not_found("test_method");
138 assert_eq!(err.code, -32601);
139 assert!(err.message.contains("test_method"));
140 }
141}