Collect all query results into one Vec
[hlquery.git] / src / main.rs
1 use std::fmt;
2 use std::fmt::Display;
3 use std::error::Error;
4 use std::env::args;
5 use std::net::{SocketAddr, SocketAddrV4, ToSocketAddrs};
6 use serde::{Serialize, Serializer};
7 use a2s::A2SClient;
8 use crate::HLQueryError::{IOError,A2SError};
9
10 #[derive(Debug, Serialize)]
11 struct HLQueryResult {
12 address: SocketAddrV4,
13 info: Result<a2s::info::Info, HLQueryError>,
14 rules: Result<Vec<a2s::rules::Rule>, HLQueryError>,
15 players: Result<Vec<a2s::players::Player>, HLQueryError>
16 }
17
18 impl HLQueryResult {
19 fn new(a2s_client: &A2SClient, server: SocketAddrV4) -> Self {
20 Self {
21 address: server,
22 info: a2s_client.info(server).map_err(From::from),
23 rules: a2s_client.rules(server).map_err(From::from),
24 players: a2s_client.players(server).map_err(From::from)
25 }
26 }
27 }
28
29 #[derive(Debug)]
30 enum HLQueryError {
31 IOError(std::io::Error),
32 A2SError(a2s::errors::Error)
33 }
34
35 impl Display for HLQueryError {
36 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37 match self {
38 IOError(e) => write!(f, "{}", e),
39 A2SError(e) => write!(f, "{}", e)
40 }
41 }
42 }
43
44 impl Error for HLQueryError {}
45
46 impl Serialize for HLQueryError {
47 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
48 where
49 S: Serializer,
50 {
51 serializer.serialize_str(&format!("{self}"))
52 }
53 }
54
55 impl From<std::io::Error> for HLQueryError {
56 fn from(e: std::io::Error) -> Self {
57 Self::IOError(e)
58 }
59 }
60
61 impl From<a2s::errors::Error> for HLQueryError {
62 fn from(e: a2s::errors::Error) -> Self {
63 Self::A2SError(e)
64 }
65 }
66
67
68 fn main() {
69 let client = A2SClient::new().unwrap();
70 let query_results: Vec<Result<Vec<HLQueryResult>, HLQueryError>> = args().skip(1)
71 .map(|arg| arg.to_socket_addrs())
72 .map(|lookup_result| match lookup_result {
73 Ok(iter_addr) => {
74 Ok(iter_addr.filter_map(|sa| match sa {
75 SocketAddr::V4(sa4) => Some(sa4),
76 _ => None
77 }))
78 },
79 Err(e) => Err(HLQueryError::IOError(e))
80 })
81 .map(|addresses| match addresses {
82 Ok(iter_addr) => Ok(iter_addr.map(|addr| HLQueryResult::new(&client, addr)).collect()),
83 Err(e) => Err(e)
84 })
85 .collect();
86
87 println!("{}\n", serde_json::to_string_pretty(&query_results).unwrap());
88 }