diff --git a/src/schema.rs b/src/schema.rs index c4a9f2f..0bfe949 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -4,7 +4,7 @@ use crate::{expr::Expression, stmt::Statement, types::*}; use serde::{Deserialize, Serialize}; -use crate::visitor::single_string_to_vec; +use strum_macros::EnumString; #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub struct Nftables { @@ -179,8 +179,8 @@ pub struct Set { pub name: String, #[serde(skip_serializing_if = "Option::is_none")] pub handle: Option, - #[serde(rename = "type", deserialize_with = "single_string_to_vec")] - pub set_type: Vec, + #[serde(rename = "type")] + pub set_type: SetTypeValue, #[serde(skip_serializing_if = "Option::is_none")] pub policy: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -201,13 +201,50 @@ pub struct Map { } #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[serde(untagged)] +/// Wrapper for single or concatenated set types. +/// The set type might be a string, such as "ipv4_addr" or an array consisting of strings (for concatenated types). +pub enum SetTypeValue { + Single(SetType), + Concatenated(Vec), +} + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, EnumString)] #[serde(rename_all = "lowercase")] +/// Describes a set’s datatype. +pub enum SetType { + // ipv4_addr, ipv6_addr, ether_addr, inet_proto, inet_service, mark + #[serde(rename = "ipv4_addr")] + #[strum(serialize="ipv4_addr")] + Ipv4Addr, + #[serde(rename = "ipv6_addr")] + #[strum(serialize="ipv6_addr")] + Ipv6Addr, + #[serde(rename = "ether_addr")] + #[strum(serialize="ether_addr")] + EtherAddr, + #[serde(rename = "inet_proto")] + #[strum(serialize="inet_proto")] + InetProto, + #[serde(rename = "inet_service")] + #[strum(serialize="inet_service")] + InetService, + #[serde(rename = "mark")] + #[strum(serialize="mark")] + Mark, +} + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +/// Describes a set’s policy. pub enum SetPolicy { Performance, Memory, } + #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)] #[serde(rename_all = "lowercase")] +/// Describes a set’s flags. pub enum SetFlag { Constant, Interval, @@ -216,6 +253,7 @@ pub enum SetFlag { #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] +/// Describes an operator on set. pub enum SetOp { Add, Update, diff --git a/src/stmt.rs b/src/stmt.rs index a19d4b7..9bdf4fa 100644 --- a/src/stmt.rs +++ b/src/stmt.rs @@ -282,7 +282,7 @@ pub struct Set { #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] -/// Operators of `Set`. +/// Operators on `Set`. pub enum SetOp { Add, Update, diff --git a/tests/helper_tests.rs b/tests/helper_tests.rs index 3c47bd5..d334af9 100644 --- a/tests/helper_tests.rs +++ b/tests/helper_tests.rs @@ -1,4 +1,4 @@ -use nftables::{batch::Batch, helper, schema, types}; +use nftables::{batch::Batch, helper, schema, types, expr}; #[test] #[ignore] @@ -17,10 +17,33 @@ fn test_apply_ruleset() { fn example_ruleset() -> schema::Nftables { let mut batch = Batch::new(); + let table_name = "test-table-01".to_string(); batch.add(schema::NfListObject::Table(schema::Table::new( types::NfFamily::IP, - "test-table-01".to_string(), + table_name.clone(), ))); + // create named set + let set_name = "test_set".to_string(); + batch.add(schema::NfListObject::Set(schema::Set { + family: types::NfFamily::IP, + table: table_name.clone(), + name: set_name.clone(), + handle: None, + set_type: schema::SetTypeValue::Single(schema::SetType::Ipv4Addr), + policy: None, + flags: None, + elem: None, + timeout: None, + gc_interval: None, + size: None, + })); + // add element to set + batch.add(schema::NfListObject::Element(schema::Element { + family: types::NfFamily::IP, + table: table_name, + name: set_name, + elem: vec![expr::Expression::String("127.0.0.1".to_string()), expr::Expression::String("127.0.0.2".to_string())], + })); batch.delete(schema::NfListObject::Table(schema::Table::new( types::NfFamily::IP, "test-table-01".to_string(),