use serde::de::{self, DeserializeSeed, Deserializer, MapAccess, SeqAccess, Visitor};
use serde::ser::{SerializeMap, Serializer};
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use std::fmt;
use std::marker::PhantomData;
#[derive(Debug, Clone, Default)]
pub struct Node {
pub node_type: Option<String>,
pub attrs: Option<Box<Map<String, Value>>>,
pub content: Option<Vec<Node>>,
pub marks: Option<Vec<Mark>>,
pub text: Option<String>,
pub extra: Option<Box<Map<String, Value>>>,
}
#[derive(Debug, Clone)]
pub struct Mark {
pub mark_type: String,
pub attrs: Option<Box<Map<String, Value>>>,
pub extra: Option<Box<Map<String, Value>>>,
}
impl Mark {
#[inline]
pub fn new(mark_type: impl Into<String>) -> Self {
Mark {
mark_type: mark_type.into(),
attrs: None,
extra: None,
}
}
#[inline]
pub fn attr(mut self, key: impl Into<String>, value: impl Into<Value>) -> Self {
self.attrs
.get_or_insert_with(Default::default)
.insert(key.into(), value.into());
self
}
#[inline]
pub fn attrs(&self) -> Option<&Map<String, Value>> {
self.attrs.as_deref()
}
#[inline]
pub fn attrs_mut(&mut self) -> &mut Map<String, Value> {
self.attrs.get_or_insert_with(Default::default)
}
#[inline]
pub fn extra(&self) -> Option<&Map<String, Value>> {
self.extra.as_deref()
}
#[inline]
pub fn extra_mut(&mut self) -> &mut Map<String, Value> {
self.extra.get_or_insert_with(Default::default)
}
}
impl Node {
#[inline]
pub fn attrs(&self) -> Option<&Map<String, Value>> {
self.attrs.as_deref()
}
#[inline]
pub fn extra(&self) -> Option<&Map<String, Value>> {
self.extra.as_deref()
}
#[inline]
pub fn extra_mut(&mut self) -> &mut Map<String, Value> {
self.extra.get_or_insert_with(Default::default)
}
#[inline]
pub fn extra_field(&self, key: &str) -> Option<&Value> {
self.extra.as_ref()?.get(key)
}
pub fn remove_extra(&mut self, key: &str) -> Option<Value> {
let m = self.extra.as_mut()?;
let prev = m.remove(key);
if m.is_empty() {
self.extra = None;
}
prev
}
}
#[inline]
pub(crate) fn extra_eq(
a: &Option<Box<Map<String, Value>>>,
b: &Option<Box<Map<String, Value>>>,
) -> bool {
match (a, b) {
(None, None) => true,
(Some(x), Some(y)) => x == y,
(Some(m), None) | (None, Some(m)) => m.is_empty(),
}
}
impl PartialEq for Node {
#[inline]
fn eq(&self, o: &Node) -> bool {
self.node_type == o.node_type
&& self.text == o.text
&& self.attrs == o.attrs
&& self.marks == o.marks
&& extra_eq(&self.extra, &o.extra)
&& self.content == o.content
}
}
impl PartialEq for Mark {
#[inline]
fn eq(&self, o: &Mark) -> bool {
self.mark_type == o.mark_type && self.attrs == o.attrs && extra_eq(&self.extra, &o.extra)
}
}
enum Key {
Type,
Attrs,
Content,
Marks,
Text,
Other(String),
}
impl Key {
#[inline]
fn known(s: &str) -> Option<Key> {
Some(match s {
"type" => Key::Type,
"attrs" => Key::Attrs,
"content" => Key::Content,
"marks" => Key::Marks,
"text" => Key::Text,
_ => return None,
})
}
}
struct KeyVisitor;
impl<'de> Visitor<'de> for KeyVisitor {
type Value = Key;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("field identifier")
}
#[inline]
fn visit_str<E: de::Error>(self, v: &str) -> Result<Key, E> {
Ok(Key::known(v).unwrap_or_else(|| Key::Other(v.to_owned())))
}
#[inline]
fn visit_string<E: de::Error>(self, v: String) -> Result<Key, E> {
Ok(Key::known(&v).unwrap_or(Key::Other(v)))
}
fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<Key, E> {
match std::str::from_utf8(v) {
Ok(s) => self.visit_str(s),
Err(_) => Err(E::invalid_value(de::Unexpected::Bytes(v), &self)),
}
}
}
impl<'de> Deserialize<'de> for Key {
#[inline]
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Key, D::Error> {
d.deserialize_identifier(KeyVisitor)
}
}
#[inline]
fn once<E: de::Error>(seen: &mut u8, bit: u8, name: &'static str) -> Result<(), E> {
if *seen & bit != 0 {
return Err(E::duplicate_field(name));
}
*seen |= bit;
Ok(())
}
#[derive(Default)]
struct Scratch {
nodes: Vec<Node>,
marks: Vec<Mark>,
}
impl<'de> Deserialize<'de> for Node {
#[inline]
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Node, D::Error> {
NodeSeed(&mut Scratch::default()).deserialize(d)
}
}
struct NodeSeed<'a>(&'a mut Scratch);
impl<'de> DeserializeSeed<'de> for NodeSeed<'_> {
type Value = Node;
#[inline]
fn deserialize<D: Deserializer<'de>>(self, d: D) -> Result<Node, D::Error> {
d.deserialize_map(self)
}
}
impl<'de> Visitor<'de> for NodeSeed<'_> {
type Value = Node;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("struct Node")
}
fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Node, A::Error> {
let mut n = Node::default();
let mut seen = 0u8;
while let Some(key) = map.next_key::<Key>()? {
match key {
Key::Type => {
once(&mut seen, 1, "type")?;
n.node_type = map.next_value()?;
}
Key::Attrs => {
once(&mut seen, 2, "attrs")?;
n.attrs = map.next_value()?;
}
Key::Content => {
once(&mut seen, 4, "content")?;
n.content = map.next_value_seed(OptVec::<Node>(self.0, PhantomData))?;
}
Key::Marks => {
once(&mut seen, 8, "marks")?;
n.marks = map.next_value_seed(OptVec::<Mark>(self.0, PhantomData))?;
}
Key::Text => {
once(&mut seen, 16, "text")?;
n.text = map.next_value()?;
}
Key::Other(k) => {
let v: Value = map.next_value()?;
n.extra_mut().insert(k, v);
}
}
}
Ok(n)
}
}
trait Stacked: Sized {
fn stack(s: &mut Scratch) -> &mut Vec<Self>;
fn next<'de, A: SeqAccess<'de>>(seq: &mut A, s: &mut Scratch)
-> Result<Option<Self>, A::Error>;
}
impl Stacked for Node {
#[inline]
fn stack(s: &mut Scratch) -> &mut Vec<Node> {
&mut s.nodes
}
#[inline]
fn next<'de, A: SeqAccess<'de>>(
seq: &mut A,
s: &mut Scratch,
) -> Result<Option<Node>, A::Error> {
seq.next_element_seed(NodeSeed(s))
}
}
impl Stacked for Mark {
#[inline]
fn stack(s: &mut Scratch) -> &mut Vec<Mark> {
&mut s.marks
}
#[inline]
fn next<'de, A: SeqAccess<'de>>(
seq: &mut A,
_: &mut Scratch,
) -> Result<Option<Mark>, A::Error> {
seq.next_element()
}
}
struct OptVec<'a, T>(&'a mut Scratch, PhantomData<T>);
impl<'de, T: Stacked> DeserializeSeed<'de> for OptVec<'_, T> {
type Value = Option<Vec<T>>;
#[inline]
fn deserialize<D: Deserializer<'de>>(self, d: D) -> Result<Self::Value, D::Error> {
d.deserialize_option(self)
}
}
impl<'de, T: Stacked> Visitor<'de> for OptVec<'_, T> {
type Value = Option<Vec<T>>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("option")
}
#[inline]
fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
Ok(None)
}
#[inline]
fn visit_unit<E: de::Error>(self) -> Result<Self::Value, E> {
Ok(None)
}
#[inline]
fn visit_some<D: Deserializer<'de>>(self, d: D) -> Result<Self::Value, D::Error> {
d.deserialize_seq(SeqVec(self.0, PhantomData)).map(Some)
}
}
struct SeqVec<'a, T>(&'a mut Scratch, PhantomData<T>);
impl<'de, T: Stacked> Visitor<'de> for SeqVec<'_, T> {
type Value = Vec<T>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("a sequence")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Vec<T>, A::Error> {
let s = self.0;
let base = T::stack(s).len();
while let Some(x) = T::next(&mut seq, s)? {
T::stack(s).push(x);
}
let st = T::stack(s);
let mut v = Vec::with_capacity(st.len() - base);
v.extend(st.drain(base..));
Ok(v)
}
}
impl Serialize for Node {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
let len = self.node_type.is_some() as usize
+ self.attrs.is_some() as usize
+ self.content.is_some() as usize
+ self.marks.is_some() as usize
+ self.text.is_some() as usize
+ self.extra.as_ref().map_or(0, |e| e.len());
let mut m = s.serialize_map(Some(len))?;
if let Some(t) = &self.node_type {
m.serialize_entry("type", t)?;
}
if let Some(a) = &self.attrs {
m.serialize_entry("attrs", a)?;
}
if let Some(c) = &self.content {
m.serialize_entry("content", c)?;
}
if let Some(mk) = &self.marks {
m.serialize_entry("marks", mk)?;
}
if let Some(t) = &self.text {
m.serialize_entry("text", t)?;
}
for (k, v) in self.extra.iter().flat_map(|e| e.iter()) {
m.serialize_entry(k, v)?;
}
m.end()
}
}
impl<'de> Deserialize<'de> for Mark {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Mark, D::Error> {
struct V;
impl<'de> Visitor<'de> for V {
type Value = Mark;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("struct Mark")
}
fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Mark, A::Error> {
let mut mark_type: Option<String> = None;
let mut attrs = None;
let mut extra: Option<Box<Map<String, Value>>> = None;
let mut seen = 0u8;
while let Some(key) = map.next_key::<Key>()? {
match key {
Key::Type => {
once(&mut seen, 1, "type")?;
mark_type = Some(map.next_value()?);
}
Key::Attrs => {
once(&mut seen, 2, "attrs")?;
attrs = map.next_value()?;
}
Key::Content => extra_entry(&mut map, &mut extra, "content")?,
Key::Marks => extra_entry(&mut map, &mut extra, "marks")?,
Key::Text => extra_entry(&mut map, &mut extra, "text")?,
Key::Other(k) => {
let v: Value = map.next_value()?;
extra.get_or_insert_with(Default::default).insert(k, v);
}
}
}
let mark_type = mark_type.ok_or_else(|| de::Error::missing_field("type"))?;
Ok(Mark {
mark_type,
attrs,
extra,
})
}
}
d.deserialize_map(V)
}
}
#[inline]
fn extra_entry<'de, A: MapAccess<'de>>(
map: &mut A,
extra: &mut Option<Box<Map<String, Value>>>,
key: &str,
) -> Result<(), A::Error> {
let v: Value = map.next_value()?;
extra
.get_or_insert_with(Default::default)
.insert(key.to_owned(), v);
Ok(())
}
impl Serialize for Mark {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
let len = 1 + self.attrs.is_some() as usize + self.extra.as_ref().map_or(0, |e| e.len());
let mut m = s.serialize_map(Some(len))?;
m.serialize_entry("type", &self.mark_type)?;
if let Some(a) = &self.attrs {
m.serialize_entry("attrs", a)?;
}
for (k, v) in self.extra.iter().flat_map(|e| e.iter()) {
m.serialize_entry(k, v)?;
}
m.end()
}
}