#[derive(Clone)]
enum FilterPropVal {
Special(Vec<FilterProp>),
Boolean(bool),
Str(String),
Uint32(u32),
Tags(Vec<String>),
}
impl FilterPropVal {
fn from_special(spec: &Vec<FilterProp>) -> FilterPropVal {
Self::Special(spec.clone())
}
fn from_tags(tags: &Vec<&str>) -> FilterPropVal {
let mut fpvtags: Vec<String> = vec![];
for tag in tags {
fpvtags.push(String::from(*tag));
}
Self::Tags(fpvtags)
}
fn as_str(&self) -> String {
match &*self {
Self::Special(filterprops) => {
let mut sstr = String::from("");
sstr += &format!("{}", filterprops.len());
for fp in filterprops {
sstr += &fp.as_str();
}
sstr
}
Self::Boolean(b) => format!("{}", *b as i32),
Self::Str(s) => String::from(s),
Self::Uint32(i) => format!("{}", i),
Self::Tags(tags) => {
let mut tags_str = String::from("");
for tag in tags {
tags_str += &tag;
tags_str += ",";
}
tags_str.pop();
tags_str
}
}
}
}
#[derive(Clone)]
struct FilterProp {
pub name: String,
pub value: FilterPropVal,
}
impl FilterProp {
fn new(name: &str, value: FilterPropVal) -> FilterProp {
FilterProp {
name: String::from(name),
value: value,
}
}
fn as_str(&self) -> String {
format!("\\{}\\{}", self.name, self.value.as_str())
}
}
pub struct Filter {
filter_lst: Vec<FilterProp>,
in_special: bool,
spec_vec: Vec<FilterProp>,
special_name: String,
}
impl Filter {
#[deprecated(since = "0.2.0", note = "Replaced with as_string (name change)")]
pub fn as_str(&self) -> String {
self.as_string()
}
pub fn as_string(&self) -> String {
let mut sstr = String::from("");
for fp in &self.filter_lst {
sstr += &fp.as_str();
}
sstr
}
pub fn new() -> Filter {
Filter {
filter_lst: vec![],
in_special: false,
spec_vec: vec![],
special_name: String::from(""),
}
}
fn push(mut self, name: &str, value: FilterPropVal) -> Filter {
if self.in_special {
self.spec_vec.push(FilterProp::new(name, value));
} else {
self.filter_lst.push(FilterProp::new(name, value));
}
self
}
fn boolean(self, name: &str, switch: bool) -> Filter {
self.push(name, FilterPropVal::Boolean(switch))
}
fn string(self, name: &str, param: &str) -> Filter {
self.push(name, FilterPropVal::Str(String::from(param)))
}
fn uint32(self, name: &str, num: u32) -> Filter {
self.push(name, FilterPropVal::Uint32(num))
}
fn vecstr(self, name: &str, tags: &Vec<&str>) -> Filter {
if tags.len() > 0 {
self.push(name, FilterPropVal::from_tags(tags))
} else {
self
}
}
fn special_start(mut self, name: &str) -> Filter {
self.spec_vec.clear();
self.in_special = true;
self.special_name = String::from(name);
self
}
pub fn nor(self) -> Filter {
self.special_start("nor")
}
pub fn nand(self) -> Filter {
self.special_start("nand")
}
pub fn end(mut self) -> Filter {
self.filter_lst.push(FilterProp::new(
&self.special_name,
FilterPropVal::from_special(&self.spec_vec),
));
self.in_special = false;
self.special_name = String::from("");
self
}
pub fn dedicated(self, is_dedicated: bool) -> Filter {
self.boolean("dedicated", is_dedicated)
}
pub fn secure(self, hasac: bool) -> Filter {
self.boolean("secure", hasac)
}
pub fn gamedir(self, modg: &str) -> Filter {
self.string("gamedir", modg)
}
pub fn map(self, mapn: &str) -> Filter {
self.string("map", mapn)
}
pub fn linux(self, runslinux: bool) -> Filter {
self.boolean("linux", runslinux)
}
pub fn password(self, protected: bool) -> Filter {
self.boolean("password", protected)
}
pub fn full(self, is_full: bool) -> Filter {
self.boolean("full", !is_full)
}
pub fn proxy(self, specprox: bool) -> Filter {
self.boolean("proxy", specprox)
}
pub fn appid(self, appid: u32) -> Filter {
self.uint32("appid", appid)
}
pub fn napp(self, appid: u32) -> Filter {
self.uint32("napp", appid)
}
pub fn empty(self, is_empty: bool) -> Filter {
if is_empty {
self.boolean("noplayers", true)
} else {
self.boolean("empty", true)
}
}
pub fn whitelisted(self, white: bool) -> Filter {
self.boolean("white", white)
}
pub fn gametype(self, tags: &Vec<&str>) -> Filter {
self.vecstr("gametype", tags)
}
pub fn gamedata(self, tags: &Vec<&str>) -> Filter {
self.vecstr("gamedata", tags)
}
pub fn gamedataor(self, tags: &Vec<&str>) -> Filter {
self.vecstr("gamedataor", tags)
}
pub fn name_match(self, hostname: &str) -> Filter {
self.string("name_match", hostname)
}
pub fn version_match(self, ver: &str) -> Filter {
self.string("version_match", ver)
}
pub fn collapse_addr_hash(self, one_server: bool) -> Filter {
self.boolean("collapse_addr_hash", one_server)
}
pub fn gameaddr(self, ipaddr: &str) -> Filter {
self.string("gameaddr", ipaddr)
}
}