use std::collections::HashMap;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::protocol::traits::{Buildable, Builder};
use crate::protocol::{enums::EnumEntry, Deprecated};
#[derive(Debug, Clone, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Enum {
name: String,
description: String,
entries: HashMap<String, EnumEntry>,
bitmask: bool,
deprecated: Option<Deprecated>,
defined_in: Vec<String>,
}
impl Buildable for Enum {
type Builder = EnumBuilder;
fn to_builder(&self) -> EnumBuilder {
EnumBuilder {
r#enum: self.clone(),
}
}
}
impl Enum {
pub fn builder() -> EnumBuilder {
EnumBuilder::new()
}
pub fn name(&self) -> &str {
&self.name
}
pub fn description(&self) -> &str {
&self.description
}
pub fn entries(&self) -> &HashMap<String, EnumEntry> {
&self.entries
}
pub fn bitmask(&self) -> bool {
self.bitmask
}
pub fn deprecated(&self) -> Option<&Deprecated> {
self.deprecated.as_ref()
}
pub fn defined_in(&self) -> &[String] {
&self.defined_in
}
}
#[derive(Debug, Clone, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct EnumBuilder {
r#enum: Enum,
}
impl Builder for EnumBuilder {
type Buildable = Enum;
fn build(&self) -> Enum {
#[allow(clippy::match_single_binding)]
match self.r#enum.clone() {
Enum {
name,
description,
entries,
bitmask,
deprecated,
defined_in,
} => Enum {
name,
description,
entries,
bitmask,
deprecated,
defined_in,
},
}
}
}
impl EnumBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn set_name(&mut self, name: String) -> &mut Self {
self.r#enum.name = name;
self
}
pub fn set_description(&mut self, description: String) -> &mut Self {
self.r#enum.description = description;
self
}
pub fn set_entries(&mut self, entries: HashMap<String, EnumEntry>) -> &mut Self {
self.r#enum.entries = entries;
self
}
pub fn set_bitmask(&mut self, bitmask: bool) -> &mut Self {
self.r#enum.bitmask = bitmask;
self
}
pub fn set_deprecated(&mut self, deprecated: Option<Deprecated>) -> &mut Self {
self.r#enum.deprecated = deprecated;
self
}
pub fn set_defined_in(&mut self, defined_in: Vec<String>) -> &mut Self {
self.r#enum.defined_in = defined_in;
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::protocol::DeprecatedSince;
#[test]
fn enum_entry_builder() {
let entries = {
let mut entries = HashMap::new();
entries.insert(
"entry".to_string(),
EnumEntry::builder().set_name("entry".to_string()).build(),
);
entries
};
let mav_enum = EnumBuilder::new()
.set_name("name".to_string())
.set_description("description".to_string())
.set_entries(entries)
.set_bitmask(true)
.set_deprecated(Some(Deprecated::new(
DeprecatedSince::default(),
"better".to_string(),
)))
.set_defined_in(vec!["unknown".to_string()])
.build();
assert!(matches!(mav_enum, Enum { .. }));
assert_eq!(mav_enum.name(), "name");
assert_eq!(mav_enum.description(), "description");
assert_eq!(mav_enum.entries().len(), 1);
assert_eq!(mav_enum.entries().get("entry").unwrap().name(), "entry");
assert!(mav_enum.bitmask);
assert_eq!(mav_enum.deprecated().unwrap().replaced_by(), "better");
assert_eq!(mav_enum.defined_in().len(), 1);
assert_eq!(mav_enum.defined_in().get(0).unwrap(), "unknown");
}
}