wooorm / markdown-rs

CommonMark compliant markdown parser in Rust with ASTs and extensions
https://docs.rs/markdown/1.0.0-alpha.18/markdown/
MIT License
836 stars 41 forks source link

MDAST: serde Serialization/Deserialization not working #72

Open nicoburniske opened 1 year ago

nicoburniske commented 1 year ago

The serialization of the mdast fails to deserialize because of a duplicate field type

#[test]
fn test_serde() {
    let markdown = "This is a **test**";
    let tree =
    markdown::to_mdast(&markdown, &markdown::ParseOptions::default()).unwrap();
    let json = serde_json::to_string(&tree).unwrap();
    let tree2: Node = serde_json::from_str(&json).unwrap();
    assert!(tree == tree2);
}

I get the following error from serde

Error("duplicate field `type`", line: 1, column: 21)

This is the generated json. It has duplicate type fields everywhere.

{
   "type":"Root",
   "type":"root",
   "children":[
      {
         "type":"Code",
         "type":"code",
         "value":"This is a **test**",
         "position":{
            "start":{
               "line":2,
               "column":1,
               "offset":1
            },
            "end":{
               "line":3,
               "column":5,
               "offset":28
            }
         },
         "lang":null,
         "meta":null
      }
   ],
   "position":{
      "start":{
         "line":1,
         "column":1,
         "offset":0
      },
      "end":{
         "line":3,
         "column":5,
         "offset":28
      }
   }
}

Looking at the AST enum and related structs they all have serde(tag, rename) macro configs, which seem to be conflicting.


#[derive(Clone, Eq, PartialEq)]
#[cfg_attr(
    feature = "serde",
    derive(serde::Serialize, serde::Deserialize),
    serde(tag = "type", rename = "type")
)]
pub enum Node {
    // Document:
    /// Root.
    Root(Root),
//..
}

#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(
    feature = "serde",
    derive(serde::Serialize, serde::Deserialize),
    serde(tag = "type", rename = "root")
)]
pub struct Root {
    // Parent.
    /// Content model.
    pub children: Vec<Node>,
    /// Positional info.
    pub position: Option<Position>,
}
wooorm commented 1 year ago

Definitely possible! PR welcome! :)

wflixu commented 4 months ago

I have the same problem, I hope the fixing PR can join in as soon as possible!