zond_engine/core/
parse.rs1pub mod ip;
17
18pub use ip::{IS_LAN_SCAN, IpParseError, to_set as to_ipset};
19
20use crate::core::models::port::PortSet;
21use crate::core::models::target::{TargetMap, TargetSet};
22
23pub fn to_target_map(
26 targets: &[String],
27 global_ports: PortSet,
28 resolver: Option<ip::ResolverFn>,
29) -> Result<TargetMap, anyhow::Error> {
30 let mut map = TargetMap::new();
31
32 for target in targets {
33 if let Some((ip_str, port_str)) = target.split_once(':') {
34 let ip_set = to_ipset(&[ip_str], resolver)
35 .map_err(|e| anyhow::anyhow!("Invalid IP in '{}': {}", ip_str, e))?;
36 let port_set = PortSet::try_from(port_str)
37 .map_err(|e| anyhow::anyhow!("Invalid Port in '{}': {}", port_str, e))?;
38 map.add_unit(TargetSet::new(ip_set, port_set));
39 } else {
40 let ip_set = to_ipset(&[target.as_str()], resolver)
41 .map_err(|e| anyhow::anyhow!("Invalid IP '{}': {}", target, e))?;
42 map.add_unit(TargetSet::new(ip_set, global_ports.clone()));
43 }
44 }
45
46 Ok(map)
47}
48
49#[cfg(test)]
59mod tests {
60 use super::*;
61 use std::net::IpAddr;
62
63 #[test]
64 fn facade_ip_resolution() {
65 let inputs = vec!["127.0.0.1", "10.0.0.1-5"];
66
67 let set = to_ipset(&inputs, None).expect("Facade should resolve IP targets");
68
69 assert_eq!(set.len(), 6);
70 assert!(set.contains(&"127.0.0.1".parse::<IpAddr>().unwrap()));
71 assert!(set.contains(&"10.0.0.3".parse::<IpAddr>().unwrap()));
72 }
73
74 #[test]
75 fn facade_empty_input() {
76 let inputs: Vec<&str> = vec![];
77 let result = to_ipset(&inputs, None);
78
79 assert!(result.is_err());
80 assert_eq!(result.unwrap_err(), IpParseError::EmptySet);
81 }
82
83 #[test]
84 fn facade_comma_splitting() {
85 let inputs = vec!["1.1.1.1, 2.2.2.2"];
86 let set = to_ipset(&inputs, None).unwrap();
87
88 assert_eq!(set.len(), 2);
89 }
90}