diff --git a/opensmtpd-derive/src/attributes.rs b/opensmtpd-derive/src/attributes.rs new file mode 100644 index 0000000..844f38e --- /dev/null +++ b/opensmtpd-derive/src/attributes.rs @@ -0,0 +1,113 @@ +// Copyright (c) 2019 Rodolphe Bréard +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use syn::parse::{Parse, ParseStream}; +use syn::punctuated::Punctuated; +use syn::{parenthesized, Ident, Result, Token}; + +#[derive(Debug)] +pub(crate) struct OpenSmtpdAttributes { + version: Ident, + subsystem: Ident, + events: Punctuated, +} + +impl Parse for OpenSmtpdAttributes { + fn parse(input: ParseStream) -> Result { + let version = input.parse()?; + let _: Token![,] = input.parse()?; + let subsystem = input.parse()?; + let _: Token![,] = input.parse()?; + let _match: Token![match] = input.parse()?; + let content; + let _ = parenthesized!(content in input); + let events = content.parse_terminated(Ident::parse)?; + Ok(OpenSmtpdAttributes { + version, + subsystem, + events, + }) + } +} + +impl OpenSmtpdAttributes { + pub(crate) fn get_version(&self) -> String { + format!( + "opensmtpd::entry::Version::{}", + self.version.to_string().to_uppercase() + ) + } + + pub(crate) fn get_subsystem(&self) -> String { + let subsystem = match self.subsystem.to_string().as_str() { + "smtp_in" => "SmtpIn", + "smtp_out" => "SmtpOut", + _ => "", + }; + format!("opensmtpd::entry::Subsystem::{}", subsystem) + } + + pub(crate) fn get_events(&self) -> String { + let events = if self + .events + .iter() + .any(|e| e.to_string().to_lowercase().as_str() == "all") + { + let lst = [ + "LinkAuth", + "LinkConnect", + "LinkDisconnect", + "LinkIdentify", + "LinkReset", + "LinkTls", + "TxBegin", + "TxMail", + "TxRcpt", + "TxEnvelope", + "TxData", + "TxCommit", + "TxRollback", + "ProtocolClient", + "ProtocolServer", + "FilterResponse", + "Timeout", + ]; + lst.iter() + .map(|e| format!("opensmtpd::entry::Event::{}", e)) + .collect::>() + } else { + self.events + .iter() + .map(|e| { + let name = match e.to_string().as_str() { + "link_auth" => "LinkAuth", + "link_connect" => "LinkConnect", + "link_disconnect" => "LinkDisconnect", + "link_identify" => "LinkIdentify", + "link_reset" => "LinkReset", + "link_tls" => "LinkTls", + "tx_begin" => "TxBegin", + "tx_mail" => "TxMail", + "tx_rcpt" => "TxRcpt", + "tx_envelope" => "TxEnvelope", + "tx_data" => "TxData", + "tx_commit" => "TxCommit", + "tx_rollback" => "TxRollback", + "protocol_client" => "ProtocolClient", + "protocol_server" => "ProtocolServer", + "filter_response" => "FilterResponse", + "timeout" => "Timeout", + _ => "", + }; + format!("opensmtpd::entry::Event::{}", name) + }) + .collect::>() + }; + format!("[{}]", events.join(", ")) + } +} diff --git a/opensmtpd-derive/src/lib.rs b/opensmtpd-derive/src/lib.rs index a9ea598..e3863d7 100644 --- a/opensmtpd-derive/src/lib.rs +++ b/opensmtpd-derive/src/lib.rs @@ -8,113 +8,12 @@ extern crate proc_macro; +mod attributes; + +use attributes::OpenSmtpdAttributes; use proc_macro::TokenStream; use quote::quote; -use syn::parse::{Parse, ParseStream}; -use syn::punctuated::Punctuated; -use syn::{parenthesized, parse_macro_input, ExprArray, Ident, ItemFn, Result, Token, TypePath}; - -#[derive(Debug)] -struct OpenSmtpdAttributes { - version: Ident, - subsystem: Ident, - events: Punctuated, -} - -impl Parse for OpenSmtpdAttributes { - fn parse(input: ParseStream) -> Result { - let version = input.parse()?; - let _: Token![,] = input.parse()?; - let subsystem = input.parse()?; - let _: Token![,] = input.parse()?; - let _match: Token![match] = input.parse()?; - let content; - let _ = parenthesized!(content in input); - let events = content.parse_terminated(Ident::parse)?; - Ok(OpenSmtpdAttributes { - version, - subsystem, - events, - }) - } -} - -impl OpenSmtpdAttributes { - fn get_version(&self) -> String { - format!( - "opensmtpd::entry::Version::{}", - self.version.to_string().to_uppercase() - ) - } - - fn get_subsystem(&self) -> String { - let subsystem = match self.subsystem.to_string().as_str() { - "smtp_in" => "SmtpIn", - "smtp_out" => "SmtpOut", - _ => "", - }; - format!("opensmtpd::entry::Subsystem::{}", subsystem) - } - - fn get_events(&self) -> String { - let events = if self - .events - .iter() - .any(|e| e.to_string().to_lowercase().as_str() == "all") - { - let lst = [ - "LinkAuth", - "LinkConnect", - "LinkDisconnect", - "LinkIdentify", - "LinkReset", - "LinkTls", - "TxBegin", - "TxMail", - "TxRcpt", - "TxEnvelope", - "TxData", - "TxCommit", - "TxRollback", - "ProtocolClient", - "ProtocolServer", - "FilterResponse", - "Timeout", - ]; - lst.iter() - .map(|e| format!("opensmtpd::entry::Event::{}", e)) - .collect::>() - } else { - self.events - .iter() - .map(|e| { - let name = match e.to_string().as_str() { - "link_auth" => "LinkAuth", - "link_connect" => "LinkConnect", - "link_disconnect" => "LinkDisconnect", - "link_identify" => "LinkIdentify", - "link_reset" => "LinkReset", - "link_tls" => "LinkTls", - "tx_begin" => "TxBegin", - "tx_mail" => "TxMail", - "tx_rcpt" => "TxRcpt", - "tx_envelope" => "TxEnvelope", - "tx_data" => "TxData", - "tx_commit" => "TxCommit", - "tx_rollback" => "TxRollback", - "protocol_client" => "ProtocolClient", - "protocol_server" => "ProtocolServer", - "filter_response" => "FilterResponse", - "timeout" => "Timeout", - _ => "", - }; - format!("opensmtpd::entry::Event::{}", name) - }) - .collect::>() - }; - format!("[{}]", events.join(", ")) - } -} +use syn::{parse_macro_input, ExprArray, ItemFn, TypePath}; macro_rules! parse_item { ($item: expr, $type: ty) => {