1#![crate_type = "proc-macro"]
33extern crate proc_macro;
34
35mod arg_parser;
36
37use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
38use std::str::FromStr;
39
40use proc_macro::{Span, TokenStream};
41
42use arg_parser::ArgParser;
43use proc_macro_error::{abort, proc_macro_error};
44
45#[cfg(feature = "std")]
46const OBJECT_PREFIX: &'static str = "std::net";
47#[cfg(not(feature = "std"))]
48const OBJECT_PREFIX: &'static str = "core::net";
49
50fn generate_ipv4_stream(addr: &Ipv4Addr) -> TokenStream {
51 let [a, b, c, d] = addr.octets();
52
53 format!("{OBJECT_PREFIX}::Ipv4Addr::new({a}, {b}, {c}, {d})")
54 .parse()
55 .unwrap()
56}
57
58fn generate_ipv4_socket_stream(socket: &SocketAddrV4) -> TokenStream {
59 let addr = socket.ip();
60 let port = socket.port();
61
62 let ip_stream = generate_ipv4_stream(addr);
63
64 format!("{OBJECT_PREFIX}::SocketAddrV4::new({ip_stream},{port})")
65 .parse()
66 .unwrap()
67}
68
69fn generate_ipv6_stream(addr: &Ipv6Addr) -> TokenStream {
70 let [a, b, c, d, e, f, g, h] = addr.segments();
71
72 format!("{OBJECT_PREFIX}::Ipv6Addr::new({a}, {b}, {c}, {d}, {e}, {f}, {g}, {h})")
73 .parse()
74 .unwrap()
75}
76
77fn generate_ipv6_socket_stream(socket: &SocketAddrV6) -> TokenStream {
78 let addr = socket.ip();
79 let port = socket.port();
80 let flow_info = socket.flowinfo();
81 let scope_id = socket.scope_id();
82
83 let ip_stream = generate_ipv6_stream(addr);
84
85 format!("{OBJECT_PREFIX}::SocketAddrV6::new({ip_stream},{port},{flow_info},{scope_id})")
86 .parse()
87 .unwrap()
88}
89
90fn generate_ip_stream(addr: &IpAddr) -> TokenStream {
91 match addr {
92 IpAddr::V4(ip) => {
93 let ip_stream = generate_ipv4_stream(ip);
94
95 format!("{OBJECT_PREFIX}::IpAddr::V4({ip_stream})")
96 .parse()
97 .unwrap()
98 }
99 IpAddr::V6(ip) => {
100 let ip_stream = generate_ipv6_stream(ip);
101
102 format!("{OBJECT_PREFIX}::IpAddr::V6({ip_stream})")
103 .parse()
104 .unwrap()
105 }
106 }
107}
108
109fn generate_ip_socket_stream(socket: &SocketAddr) -> TokenStream {
110 match socket {
111 SocketAddr::V4(socket) => {
112 let socket_stream = generate_ipv4_socket_stream(socket);
113
114 format!("{OBJECT_PREFIX}::SocketAddr::V4({socket_stream})")
115 .parse()
116 .unwrap()
117 }
118 SocketAddr::V6(socket) => {
119 let socket_stream = generate_ipv6_socket_stream(socket);
120
121 format!("{OBJECT_PREFIX}::SocketAddr::V6({socket_stream})")
122 .parse()
123 .unwrap()
124 }
125 }
126}
127
128fn report_error<T>(value: Result<T, arg_parser::Error>) -> T {
129 match value {
130 Ok(v) => v,
131 Err(e) => {
132 abort!(e.span(), "{}", e);
133 }
134 }
135}
136
137fn report_too_few_arguments_error(given: usize, expected: usize) -> ! {
138 abort!(
139 Span::call_site(),
140 "Too few argument: Given {}, expected {}",
141 given,
142 expected
143 );
144}
145
146fn report_too_many_arguments_error(span: Span, given: usize, expected: usize) -> ! {
147 abort!(
148 span,
149 "Too many arguments: Given {}, expected {}",
150 given,
151 expected
152 );
153}
154
155#[proc_macro_error]
170#[proc_macro]
171pub fn ipv4(item: TokenStream) -> TokenStream {
172 let mut parser = ArgParser::from(item);
173
174 let ip = if let Some((v, span)) = report_error(parser.next_string()) {
175 match Ipv4Addr::from_str(v.as_str()) {
176 Ok(v) => v,
177 Err(_) => {
178 abort!(
179 span,
180 "The given address `{}` is not a valid IPv4 address",
181 v
182 );
183 }
184 }
185 } else {
186 report_too_few_arguments_error(0, 1);
187 };
188
189 if let Some(span) = report_error(parser.ignore_next()) {
190 report_too_many_arguments_error(span, parser.count_arguments(), 1);
191 }
192
193 generate_ipv4_stream(&ip)
194}
195
196#[proc_macro_error]
211#[proc_macro]
212pub fn ipv6(item: TokenStream) -> TokenStream {
213 let mut parser = ArgParser::from(item);
214
215 let ip = if let Some((v, span)) = report_error(parser.next_string()) {
216 match Ipv6Addr::from_str(v.as_str()) {
217 Ok(v) => v,
218 Err(_) => {
219 abort!(
220 span,
221 "The given address `{}` is not a valid IPv6 address",
222 v
223 );
224 }
225 }
226 } else {
227 report_too_few_arguments_error(0, 1);
228 };
229
230 if let Some(span) = report_error(parser.ignore_next()) {
231 report_too_many_arguments_error(span, parser.count_arguments(), 1);
232 }
233
234 generate_ipv6_stream(&ip)
235}
236
237#[proc_macro_error]
254#[proc_macro]
255pub fn ip(item: TokenStream) -> TokenStream {
256 let mut parser = ArgParser::from(item);
257
258 let ip = if let Some((v, span)) = report_error(parser.next_string()) {
259 match IpAddr::from_str(v.as_str()) {
260 Ok(v) => v,
261 Err(_) => {
262 abort!(span, "The given address `{}` is not a valid IP address", v);
263 }
264 }
265 } else {
266 report_too_few_arguments_error(0, 1);
267 };
268
269 if let Some(span) = report_error(parser.ignore_next()) {
270 report_too_many_arguments_error(span, parser.count_arguments(), 1);
271 }
272
273 generate_ip_stream(&ip)
274}
275
276#[proc_macro_error]
291#[proc_macro]
292pub fn socketv4(item: TokenStream) -> TokenStream {
293 let mut parser = ArgParser::from(item);
294
295 let socket = if let Some((v, span)) = report_error(parser.next_string()) {
296 match SocketAddrV4::from_str(v.as_str()) {
297 Ok(v) => v,
298 Err(_) => {
299 abort!(
300 span,
301 "The given address `{}` is not a valid IPv4 socket address",
302 v
303 );
304 }
305 }
306 } else {
307 report_too_few_arguments_error(0, 1);
308 };
309
310 if let Some(span) = report_error(parser.ignore_next()) {
311 report_too_many_arguments_error(span, parser.count_arguments(), 1);
312 }
313
314 generate_ipv4_socket_stream(&socket)
315}
316
317#[proc_macro_error]
333#[proc_macro]
334pub fn socketv6(item: TokenStream) -> TokenStream {
335 let mut parser = ArgParser::from(item);
336
337 let mut socket = if let Some((v, span)) = report_error(parser.next_string()) {
338 match SocketAddrV6::from_str(v.as_str()) {
339 Ok(v) => v,
340 Err(_) => {
341 abort!(
342 span,
343 "The given address `{}` is not a valid IPv6 socket address",
344 v
345 );
346 }
347 }
348 } else {
349 report_too_few_arguments_error(0, 1);
350 };
351
352 if let Some((flow_info, _)) = report_error(parser.next_integer()) {
353 socket.set_flowinfo(flow_info);
354 }
355
356 if let Some((scope_id, _)) = report_error(parser.next_integer()) {
357 socket.set_scope_id(scope_id)
358 }
359
360 if let Some(span) = report_error(parser.ignore_next()) {
361 report_too_many_arguments_error(span, parser.count_arguments(), 3);
362 }
363
364 generate_ipv6_socket_stream(&socket)
365}
366
367#[proc_macro_error]
383#[proc_macro]
384pub fn socket(item: TokenStream) -> TokenStream {
385 let mut parser = ArgParser::from(item);
386
387 let socket = if let Some((v, span)) = report_error(parser.next_string()) {
388 match SocketAddr::from_str(v.as_str()) {
389 Ok(v) => v,
390 Err(_) => {
391 abort!(
392 span,
393 "The given address `{}` is not a valid socket address",
394 v
395 );
396 }
397 }
398 } else {
399 report_too_few_arguments_error(0, 1);
400 };
401
402 if let Some(span) = report_error(parser.ignore_next()) {
403 report_too_many_arguments_error(span, parser.count_arguments(), 1);
404 }
405
406 generate_ip_socket_stream(&socket)
407}