use serde::Deserialize;
use serde::Serialize;
use crate::ser::tags::Id;
use crate::ser::tags::Tag;
#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum TagLit {
Pos(Tag),
Neg(Tag),
}
impl TagLit {
pub fn id(&self) -> Id {
match self {
TagLit::Pos(tag) | TagLit::Neg(tag) => tag.id,
}
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
struct ViewImpl {
name: String,
lits: Vec<Vec<TagLit>>,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
#[serde(untagged)]
enum ViewTuple {
Tuple((ViewImpl, Option<usize>)),
View(ViewImpl),
}
impl From<ViewTuple> for View {
fn from(other: ViewTuple) -> Self {
let deprecated = matches!(other, ViewTuple::Tuple(..));
match other {
ViewTuple::View(view) | ViewTuple::Tuple((view, ..)) => {
let ViewImpl { name, lits } = view;
View {
name,
lits,
deprecated,
}
},
}
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
#[serde(from = "ViewTuple")]
pub struct View {
pub name: String,
pub lits: Vec<Vec<TagLit>>,
#[serde(skip_serializing)]
pub deprecated: bool,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ser::backends::Backend;
use crate::ser::backends::Json;
use crate::ser::id::Id;
#[test]
fn serialize_deserialize_view() {
let tag1 = Tag {
id: Id::try_from(1).unwrap(),
};
let tag2 = Tag {
id: Id::try_from(2).unwrap(),
};
let tag3 = Tag {
id: Id::try_from(3).unwrap(),
};
let tag4 = Tag {
id: Id::try_from(4).unwrap(),
};
let view = View {
name: "test-view".to_string(),
lits: vec![
vec![TagLit::Pos(tag1)],
vec![TagLit::Pos(tag2), TagLit::Neg(tag3)],
vec![TagLit::Neg(tag4), TagLit::Pos(tag2)],
],
deprecated: false,
};
let serialized = Json::serialize(&view).unwrap();
let deserialized = <Json as Backend<View>>::deserialize(&serialized).unwrap();
assert_eq!(deserialized, view);
}
}