use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ComposeStyle {
Stacked,
InlineIcon,
BadgeInline,
}
impl ComposeStyle {
pub fn slug(self) -> &'static str {
match self {
ComposeStyle::Stacked => "stacked",
ComposeStyle::InlineIcon => "inline_icon",
ComposeStyle::BadgeInline => "badge_inline",
}
}
pub fn from_slug(slug: &str) -> Option<Self> {
match slug {
"stacked" => Some(ComposeStyle::Stacked),
"inline_icon" => Some(ComposeStyle::InlineIcon),
"badge_inline" => Some(ComposeStyle::BadgeInline),
_ => None,
}
}
pub fn all() -> &'static [ComposeStyle] {
&[
ComposeStyle::Stacked,
ComposeStyle::InlineIcon,
ComposeStyle::BadgeInline,
]
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CellComposition {
pub id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
pub style: ComposeStyle,
pub primary_field: String,
#[serde(default)]
pub secondary_fields: Vec<String>,
}
impl CellComposition {
pub fn all_fields(&self) -> Vec<&str> {
let mut names = Vec::with_capacity(1 + self.secondary_fields.len());
names.push(self.primary_field.as_str());
names.extend(self.secondary_fields.iter().map(String::as_str));
names
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn style_slug_roundtrips_and_matches_serde() {
for style in ComposeStyle::all() {
assert_eq!(ComposeStyle::from_slug(style.slug()), Some(*style));
let json = serde_json::to_string(style).unwrap();
assert_eq!(json, format!("\"{}\"", style.slug()));
}
assert_eq!(ComposeStyle::from_slug("nope"), None);
}
}