Refactor the code generator

This commit is contained in:
moznion
2020-11-25 01:37:26 +09:00
parent a8cfc1e9c0
commit 2d9816a3da
2 changed files with 84 additions and 85 deletions
+73 -85
View File
@@ -28,24 +28,23 @@ struct RadiusValue {
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
enum RadiusAttributeValueType { enum RadiusAttributeValueType {
STRING, String,
USER_PASSWORD, UserPassword,
OCTETS, Octets,
IPADDR, IpAddr,
INTEGER, Integer,
VSA, VSA,
} }
impl FromStr for RadiusAttributeValueType { impl FromStr for RadiusAttributeValueType {
type Err = (); type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_uppercase().as_str() { match s {
"STRING" => Ok(RadiusAttributeValueType::STRING), "string" => Ok(RadiusAttributeValueType::String),
"USER_PASSWORD" => Ok(RadiusAttributeValueType::USER_PASSWORD), "octets" => Ok(RadiusAttributeValueType::Octets),
"OCTETS" => Ok(RadiusAttributeValueType::OCTETS), "ipaddr" => Ok(RadiusAttributeValueType::IpAddr),
"IPADDR" => Ok(RadiusAttributeValueType::IPADDR), "integer" => Ok(RadiusAttributeValueType::Integer),
"INTEGER" => Ok(RadiusAttributeValueType::INTEGER), "vsa" => Ok(RadiusAttributeValueType::VSA),
"VSA" => Ok(RadiusAttributeValueType::VSA),
_ => Err(()), _ => Err(()),
} }
} }
@@ -91,7 +90,7 @@ fn main() {
generate_footer(&mut buf_writer); generate_footer(&mut buf_writer);
} }
fn generate_header(w: &mut BufWriter<File>, struct_name: &String) { fn generate_header(w: &mut BufWriter<File>, struct_name: &str) {
let code = format!( let code = format!(
"// Code generated by machine generator; DO NOT EDIT. "// Code generated by machine generator; DO NOT EDIT.
@@ -122,38 +121,40 @@ fn generate_attributes_code(w: &mut BufWriter<File>, attrs: &[RadiusAttribute])
} }
fn generate_attribute_code(w: &mut BufWriter<File>, attr: &RadiusAttribute) { fn generate_attribute_code(w: &mut BufWriter<File>, attr: &RadiusAttribute) {
let attr_name = attr.name.clone();
let type_identifier = format!("{}_TYPE", attr_name.to_screaming_snake_case());
let type_calling = format!("Self::{}", type_identifier);
let type_value = attr.typ;
let method_identifier = attr_name.to_snake_case();
generate_common_attribute_code(w, &attr_name, &type_identifier, &type_calling, type_value);
match attr.value_type { match attr.value_type {
RadiusAttributeValueType::STRING => { RadiusAttributeValueType::String => {
generate_common_attribute_code(w, attr); generate_string_attribute_code(w, &method_identifier, &type_calling)
generate_string_attribute_code(w, attr);
} }
RadiusAttributeValueType::USER_PASSWORD => { RadiusAttributeValueType::UserPassword => {
generate_common_attribute_code(w, attr); generate_user_password_attribute_code(w, &method_identifier, &type_calling)
generate_user_password_attribute_code(w, attr);
} }
RadiusAttributeValueType::OCTETS => { RadiusAttributeValueType::Octets => {
generate_common_attribute_code(w, attr); generate_octets_attribute_code(w, &method_identifier, &type_calling)
generate_octets_attribute_code(w, attr);
} }
RadiusAttributeValueType::IPADDR => { RadiusAttributeValueType::IpAddr => {
generate_common_attribute_code(w, attr); generate_ipaddr_attribute_code(w, &method_identifier, &type_calling)
generate_ipaddr_attribute_code(w, attr);
} }
RadiusAttributeValueType::INTEGER => { RadiusAttributeValueType::Integer => {
generate_common_attribute_code(w, attr); generate_integer_attribute_code(w, &method_identifier, &type_calling)
generate_integer_attribute_code(w, attr);
} }
// RadiusAttributeValueType::VSA => generate_vsa_attribute_code(w, attr), RadiusAttributeValueType::VSA => generate_vsa_attribute_code(),
_ => {}
} }
} }
fn generate_common_attribute_code(w: &mut BufWriter<File>, attr: &RadiusAttribute) { fn generate_common_attribute_code(
let attr_name = attr.name.clone(); w: &mut BufWriter<File>,
attr_name: &str,
let type_identifier = format!("{}_TYPE", attr_name.to_screaming_snake_case()); type_identifier: &str,
let type_calling = format!("Self::{}", type_identifier); type_calling: &str,
type_value: u8,
) {
let code = format!( let code = format!(
" "
pub const {type_identifier}: AVPType = {type_value}; pub const {type_identifier}: AVPType = {type_value};
@@ -170,37 +171,33 @@ pub fn lookup_all_{method_identifier}(packet: &Packet) -> Vec<&Attribute> {{
method_identifier = attr_name.to_snake_case(), method_identifier = attr_name.to_snake_case(),
type_identifier = type_identifier, type_identifier = type_identifier,
type_calling = type_calling, type_calling = type_calling,
type_value = attr.typ, type_value = type_value,
); );
w.write_all(code.as_bytes()).unwrap(); w.write_all(code.as_bytes()).unwrap();
} }
fn generate_string_attribute_code(w: &mut BufWriter<File>, attr: &RadiusAttribute) { fn generate_string_attribute_code(
let attr_name = attr.name.clone(); w: &mut BufWriter<File>,
method_identifier: &str,
let type_identifier = format!("{}_TYPE", attr_name.to_screaming_snake_case()); type_calling: &str,
let type_calling = format!("Self::{}", type_identifier); ) {
let code = format!( let code = format!(
"pub fn add_{method_identifier}(packet: &mut Packet, value: &str) {{ "pub fn add_{method_identifier}(packet: &mut Packet, value: &str) {{
let attr = Attribute::from_string(value); let attr = Attribute::from_string(value);
packet.add({type_calling}, &attr); packet.add({type_calling}, &attr);
}} }}
", ",
method_identifier = attr_name.to_snake_case(), method_identifier = method_identifier,
type_calling = type_calling, type_calling = type_calling,
); );
w.write_all(code.as_bytes()).unwrap(); w.write_all(code.as_bytes()).unwrap();
} }
fn generate_user_password_attribute_code(w: &mut BufWriter<File>, attr: &RadiusAttribute) { fn generate_user_password_attribute_code(
let attr_name = attr.name.clone(); w: &mut BufWriter<File>,
method_identifier: &str,
let type_identifier = format!("{}_TYPE", attr_name.to_screaming_snake_case()); type_calling: &str,
let type_calling = format!("Self::{}", type_identifier); ) {
let code = format!( let code = format!(
"pub fn add_{method_identifier}(packet: &mut Packet, value: &[u8]) -> Result<(), String> {{ "pub fn add_{method_identifier}(packet: &mut Packet, value: &[u8]) -> Result<(), String> {{
let attr = Attribute::from_user_password(value, packet.get_secret(), packet.get_authenticator())?; let attr = Attribute::from_user_password(value, packet.get_secret(), packet.get_authenticator())?;
@@ -208,72 +205,65 @@ fn generate_user_password_attribute_code(w: &mut BufWriter<File>, attr: &RadiusA
Ok(()) Ok(())
}} }}
", ",
method_identifier = attr_name.to_snake_case(), method_identifier = method_identifier,
type_calling = type_calling, type_calling = type_calling,
); );
w.write_all(code.as_bytes()).unwrap(); w.write_all(code.as_bytes()).unwrap();
} }
fn generate_octets_attribute_code(w: &mut BufWriter<File>, attr: &RadiusAttribute) { fn generate_octets_attribute_code(
let attr_name = attr.name.clone(); w: &mut BufWriter<File>,
method_identifier: &str,
let type_identifier = format!("{}_TYPE", attr_name.to_screaming_snake_case()); type_calling: &str,
let type_calling = format!("Self::{}", type_identifier); ) {
let code = format!( let code = format!(
"pub fn add_{method_identifier}(packet: &mut Packet, value: &[u8]) {{ "pub fn add_{method_identifier}(packet: &mut Packet, value: &[u8]) {{
let attr = Attribute::from_bytes(value); let attr = Attribute::from_bytes(value);
packet.add({type_calling}, &attr); packet.add({type_calling}, &attr);
}} }}
", ",
method_identifier = attr_name.to_snake_case(), method_identifier = method_identifier,
type_calling = type_calling, type_calling = type_calling,
); );
w.write_all(code.as_bytes()).unwrap(); w.write_all(code.as_bytes()).unwrap();
} }
fn generate_ipaddr_attribute_code(w: &mut BufWriter<File>, attr: &RadiusAttribute) { fn generate_ipaddr_attribute_code(
let attr_name = attr.name.clone(); w: &mut BufWriter<File>,
method_identifier: &str,
let type_identifier = format!("{}_TYPE", attr_name.to_screaming_snake_case()); type_calling: &str,
let type_calling = format!("Self::{}", type_identifier); ) {
let code = format!( let code = format!(
"pub fn add_{method_identifier}(packet: &mut Packet, value: &Ipv4Addr) {{ "pub fn add_{method_identifier}(packet: &mut Packet, value: &Ipv4Addr) {{
let attr = Attribute::from_ipv4(value); let attr = Attribute::from_ipv4(value);
packet.add({type_calling}, &attr); packet.add({type_calling}, &attr);
}} }}
", ",
method_identifier = attr_name.to_snake_case(), method_identifier = method_identifier,
type_calling = type_calling, type_calling = type_calling,
); );
w.write_all(code.as_bytes()).unwrap(); w.write_all(code.as_bytes()).unwrap();
} }
fn generate_integer_attribute_code(w: &mut BufWriter<File>, attr: &RadiusAttribute) { fn generate_integer_attribute_code(
let attr_name = attr.name.clone(); w: &mut BufWriter<File>,
method_identifier: &str,
let type_identifier = format!("{}_TYPE", attr_name.to_screaming_snake_case()); type_calling: &str,
let type_calling = format!("Self::{}", type_identifier); ) {
let code = format!( let code = format!(
"pub fn add_{method_identifier}(packet: &mut Packet, value: u32) {{ "pub fn add_{method_identifier}(packet: &mut Packet, value: u32) {{
let attr = Attribute::from_u32(value); let attr = Attribute::from_u32(value);
packet.add({type_calling}, &attr); packet.add({type_calling}, &attr);
}} }}
", ",
method_identifier = attr_name.to_snake_case(), method_identifier = method_identifier,
type_calling = type_calling, type_calling = type_calling,
); );
w.write_all(code.as_bytes()).unwrap(); w.write_all(code.as_bytes()).unwrap();
} }
fn generate_vsa_attribute_code(w: &mut BufWriter<File>, attr: &RadiusAttribute) { fn generate_vsa_attribute_code() {
unimplemented!() // NOP
} }
type DictParsed = (Vec<RadiusAttribute>, HashMap<String, Vec<RadiusValue>>); type DictParsed = (Vec<RadiusAttribute>, HashMap<String, Vec<RadiusValue>>);
@@ -312,16 +302,14 @@ fn parse_dict_file(dict_file_path: &Path) -> Result<DictParsed, String> {
let typ = match RadiusAttributeValueType::from_str(type_descriptions[0]) { let typ = match RadiusAttributeValueType::from_str(type_descriptions[0]) {
Ok(t) => { Ok(t) => {
if t == RadiusAttributeValueType::STRING && is_encrypt { if t == RadiusAttributeValueType::String && is_encrypt {
RadiusAttributeValueType::USER_PASSWORD RadiusAttributeValueType::UserPassword
} else { } else {
t t
} }
} }
Err(_) => { Err(_) => {
return Err( return Err(format!("invalid type has come => {}", type_descriptions[0]));
format!("invalid type has come => {}", type_descriptions[0]).to_owned()
);
} }
}; };
+11
View File
@@ -355,6 +355,17 @@ impl RFC2865 {
packet.add(Self::CLASS_TYPE, &attr); packet.add(Self::CLASS_TYPE, &attr);
} }
pub const VENDOR_SPECIFIC_TYPE: AVPType = 26;
pub fn delete_vendor_specific(packet: &mut Packet) {
packet.delete(Self::VENDOR_SPECIFIC_TYPE);
}
pub fn lookup_vendor_specific(packet: &Packet) -> Option<&Attribute> {
packet.lookup(Self::VENDOR_SPECIFIC_TYPE)
}
pub fn lookup_all_vendor_specific(packet: &Packet) -> Vec<&Attribute> {
packet.lookup_all(Self::VENDOR_SPECIFIC_TYPE)
}
pub const SESSION_TIMEOUT_TYPE: AVPType = 27; pub const SESSION_TIMEOUT_TYPE: AVPType = 27;
pub fn delete_session_timeout(packet: &mut Packet) { pub fn delete_session_timeout(packet: &mut Packet) {
packet.delete(Self::SESSION_TIMEOUT_TYPE); packet.delete(Self::SESSION_TIMEOUT_TYPE);