use crate::model::{Loss, Mark};
use serde_json::Value;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IslandType {
Table,
Image,
}
impl IslandType {
pub const ALL: &'static [IslandType] = &[IslandType::Table, IslandType::Image];
pub fn as_str(self) -> &'static str {
match self {
Self::Table => "table",
Self::Image => "image",
}
}
pub fn parse(s: &str) -> Option<Self> {
match s {
"table" => Some(Self::Table),
"image" => Some(Self::Image),
_ => None,
}
}
pub fn default_loss(self) -> Loss {
match self {
Self::Table => Loss::Lossless,
Self::Image => Loss::Lossless,
}
}
pub fn block_only(self) -> bool {
match self {
Self::Table => true,
Self::Image => false,
}
}
pub fn cell_marks(self, props: &Value) -> Vec<(String, Vec<Mark>)> {
match self {
Self::Table => crate::serial::table_cells(props),
Self::Image => Vec::new(),
}
}
pub fn reject_unknown_cell_mark(self, props: &Value) -> Result<(), crate::serial::ParseError> {
match self {
Self::Table => crate::serial::reject_unknown_cell_mark_name(props),
Self::Image => Ok(()),
}
}
pub fn normalize_props(self, props: &mut Value) {
match self {
Self::Table => crate::serial::normalize_table_props(props),
Self::Image => {}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn known_types_round_trip() {
for k in [IslandType::Table, IslandType::Image] {
assert_eq!(IslandType::parse(k.as_str()), Some(k));
}
}
#[test]
fn normalize_props_settles_every_props_shape_on_one_column_count() {
for props in [
serde_json::json!({"header": ["h"], "aligns": "bogus", "rows": [["a"]]}),
serde_json::json!({"header": "bogus", "aligns": ["left"], "rows": [["a"]]}),
serde_json::json!({"header": ["h"], "aligns": ["left"], "rows": ["bogus"]}),
serde_json::json!({"header": ["h"], "aligns": 7, "rows": [[], null]}),
] {
let mut props = props;
IslandType::Table.normalize_props(&mut props);
let len = |k: &str| props[k].as_array().expect("an array").len();
let cols = len("header");
assert_eq!(len("aligns"), cols, "aligns off the column count: {props}");
for row in props["rows"].as_array().expect("an array") {
let width = row.as_array().expect("an array").len();
assert_eq!(width, cols, "row off the column count: {props}");
}
let once = props.clone();
IslandType::Table.normalize_props(&mut props);
assert_eq!(props, once, "normalize_props is not a fixed point");
}
}
}