feat(macro): Add mac_address macro
This commit is contained in:
parent
1e0c2eb470
commit
d0d81af796
1
harmony-rs/Cargo.lock
generated
1
harmony-rs/Cargo.lock
generated
@ -909,6 +909,7 @@ dependencies = [
|
||||
name = "harmony_macros"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"harmony",
|
||||
"quote",
|
||||
"syn 2.0.90",
|
||||
]
|
||||
|
||||
@ -3,9 +3,7 @@ use derive_new::new;
|
||||
use crate::{hardware::ManagementInterface, topology::MacAddress};
|
||||
|
||||
#[derive(new)]
|
||||
pub struct OPNSenseManagementInterface {
|
||||
mac: MacAddress,
|
||||
}
|
||||
pub struct OPNSenseManagementInterface {}
|
||||
|
||||
impl ManagementInterface for OPNSenseManagementInterface {
|
||||
fn boot_to_pxe(&self) {
|
||||
@ -13,7 +11,7 @@ impl ManagementInterface for OPNSenseManagementInterface {
|
||||
}
|
||||
|
||||
fn get_mac_address(&self) -> MacAddress {
|
||||
self.mac.clone()
|
||||
todo!("OPNSense can have multiple mac addresses using SSH. I'm not sure it even belongs in the ManagementInterface trait")
|
||||
}
|
||||
|
||||
fn get_supported_protocol_names(&self) -> String {
|
||||
|
||||
@ -7,5 +7,6 @@ version = "1.0.0"
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
harmony = { version = "0.1.0", path = "../harmony" }
|
||||
quote = "1.0.37"
|
||||
syn = "2.0.90"
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
extern crate proc_macro;
|
||||
|
||||
use harmony::topology::MacAddress;
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, LitStr};
|
||||
use syn::{LitStr, parse_macro_input};
|
||||
|
||||
#[proc_macro]
|
||||
pub fn ip(input: TokenStream) -> TokenStream {
|
||||
@ -10,14 +11,56 @@ pub fn ip(input: TokenStream) -> TokenStream {
|
||||
let ip_str = input.value();
|
||||
|
||||
if let Ok(_) = ip_str.parse::<std::net::Ipv4Addr>() {
|
||||
let expanded = quote! { std::net::IpAddr::V4(#ip_str.parse::<std::net::Ipv4Addr>().unwrap()) };
|
||||
let expanded =
|
||||
quote! { std::net::IpAddr::V4(#ip_str.parse::<std::net::Ipv4Addr>().unwrap()) };
|
||||
return TokenStream::from(expanded);
|
||||
}
|
||||
|
||||
if let Ok(_) = ip_str.parse::<std::net::Ipv6Addr>() {
|
||||
let expanded = quote! { std::net::IpAddr::V4(#ip_str.parse::<std::net::Ipv6Addr>().unwrap()) };
|
||||
let expanded =
|
||||
quote! { std::net::IpAddr::V4(#ip_str.parse::<std::net::Ipv6Addr>().unwrap()) };
|
||||
return TokenStream::from(expanded);
|
||||
}
|
||||
|
||||
panic!("Invalid IP address: {}", ip_str);
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn mac_address(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as LitStr);
|
||||
let mac_str = input.value();
|
||||
|
||||
match parse_mac_address(&mac_str) {
|
||||
Ok(bytes) => {
|
||||
let b0 = bytes[0];
|
||||
let b1 = bytes[1];
|
||||
let b2 = bytes[2];
|
||||
let b3 = bytes[3];
|
||||
let b4 = bytes[4];
|
||||
let b5 = bytes[5];
|
||||
|
||||
quote! {
|
||||
MacAddress( [#b0, #b1, #b2, #b3, #b4, #b5] )
|
||||
}
|
||||
.into()
|
||||
}
|
||||
Err(err) => syn::Error::new(input.span(), err).to_compile_error().into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_mac_address(mac: &str) -> Result<[u8; 6], String> {
|
||||
let parts: Vec<&str> = mac.split(':').collect();
|
||||
if parts.len() != 6 {
|
||||
return Err("MAC address must contain exactly six octets separated by colons".to_string());
|
||||
}
|
||||
|
||||
let mut bytes = [0u8; 6];
|
||||
for (i, part) in parts.iter().enumerate() {
|
||||
match u8::from_str_radix(part, 16) {
|
||||
Ok(byte) => bytes[i] = byte,
|
||||
Err(_) => return Err(format!("Invalid MAC address octet: {}", part)),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(bytes)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user