Add serde support

This commit is contained in:
Isaac Mills 2024-04-04 17:50:55 -04:00
parent 8239b2b51d
commit b7c31f6895
Signed by: fnmain
GPG key ID: B67D7410F33A0F61
16 changed files with 32 additions and 148 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
target/

23
Cargo.lock generated
View file

@ -181,7 +181,7 @@ checksum = "377af281d8f23663862a7c84623bc5dcf7f8c44b13c7496a590bdc157f941a43"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.16", "syn 2.0.58",
"synstructure", "synstructure",
] ]
@ -289,6 +289,7 @@ name = "jotdown"
version = "0.3.2" version = "0.3.2"
dependencies = [ dependencies = [
"databake", "databake",
"serde",
] ]
[[package]] [[package]]
@ -405,9 +406,9 @@ dependencies = [
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.26" version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -444,22 +445,22 @@ dependencies = [
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.152" version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.152" version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 1.0.107", "syn 2.0.58",
] ]
[[package]] [[package]]
@ -486,9 +487,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.16" version = "2.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -503,7 +504,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.16", "syn 2.0.58",
] ]
[[package]] [[package]]

View file

@ -46,3 +46,4 @@ parser = []
[dependencies] [dependencies]
databake = { version = "0.1.7", features = ["derive"] } databake = { version = "0.1.7", features = ["derive"] }
serde = { version = "1.0.197", features = ["derive"] }

View file

@ -6,7 +6,7 @@ edition = "2021"
[dev-dependencies] [dev-dependencies]
criterion = { version = "0.4", default-features = false } criterion = { version = "0.4", default-features = false }
bench-input = { path = "../input" } bench-input = { path = "../input" }
jotdown = { path = "../../" } jotdown = { path = "../../", features = ["html", "parser"] }
[[bench]] [[bench]]
name = "criterion" name = "criterion"

View file

@ -12,7 +12,7 @@ repository = "https://github.com/hellux/jotdown"
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies] [dependencies]
jotdown = { path = "../../" } jotdown = { path = "../../", features = ["parser"] }
wasm-bindgen = { version = "0.2", default-features = false } wasm-bindgen = { version = "0.2", default-features = false }
[dependencies.web-sys] [dependencies.web-sys]

BIN
jotdown Executable file

Binary file not shown.

View file

@ -1,4 +1,5 @@
use databake::Bake; use databake::Bake;
use serde::{Deserialize, Serialize};
use crate::CowStr; use crate::CowStr;
use std::{borrow::Cow, fmt}; use std::{borrow::Cow, fmt};
@ -35,7 +36,7 @@ pub fn valid(src: &str) -> usize {
/// Stores an attribute value that supports backslash escapes of ASCII punctuation upon displaying, /// Stores an attribute value that supports backslash escapes of ASCII punctuation upon displaying,
/// without allocating. /// without allocating.
#[derive(Clone, Debug, Eq, PartialEq, Bake)] #[derive(Clone, Debug, Eq, PartialEq, Bake, Deserialize, Serialize)]
#[databake(path = jotdown)] #[databake(path = jotdown)]
pub struct AttributeValue<'s> { pub struct AttributeValue<'s> {
raw: CowStr<'s>, raw: CowStr<'s>,
@ -123,9 +124,9 @@ impl<'s> Iterator for AttributeValueParts<'s> {
// Attributes are relatively rare, we choose to pay 8 bytes always and sometimes an extra // Attributes are relatively rare, we choose to pay 8 bytes always and sometimes an extra
// indirection instead of always 24 bytes. // indirection instead of always 24 bytes.
#[allow(clippy::box_vec)] #[allow(clippy::box_vec)]
#[derive(Clone, PartialEq, Eq, Default, Bake)] #[derive(Clone, PartialEq, Eq, Default, Bake, Deserialize, Serialize)]
#[databake(path = jotdown)] #[databake(path = jotdown)]
pub struct Attributes<'s>(pub Option<Cow<'s, [(&'s str, AttributeValue<'s>)]>>); pub struct Attributes<'s>(#[serde(borrow)] pub Option<Cow<'s, [(&'s str, AttributeValue<'s>)]>>);
impl<'s> Attributes<'s> { impl<'s> Attributes<'s> {
/// Create an empty collection. /// Create an empty collection.

View file

@ -68,6 +68,7 @@ mod lex;
pub use attr::{AttributeValue, AttributeValueParts, Attributes}; pub use attr::{AttributeValue, AttributeValueParts, Attributes};
use databake::Bake; use databake::Bake;
use serde::{Deserialize, Serialize};
type CowStr<'s> = std::borrow::Cow<'s, str>; type CowStr<'s> = std::borrow::Cow<'s, str>;
@ -203,7 +204,7 @@ impl<'s> AsRef<Event<'s>> for &Event<'s> {
/// multiple events. [`Container`] elements are represented by a [`Event::Start`] followed by /// multiple events. [`Container`] elements are represented by a [`Event::Start`] followed by
/// events representing its content, and finally a [`Event::End`]. Atomic elements without any /// events representing its content, and finally a [`Event::End`]. Atomic elements without any
/// inside elements are represented by a single event. /// inside elements are represented by a single event.
#[derive(Debug, Clone, PartialEq, Eq, Bake)] #[derive(Debug, Clone, PartialEq, Eq, Bake, Deserialize, Serialize)]
#[databake(path = jotdown)] #[databake(path = jotdown)]
pub enum Event<'s> { pub enum Event<'s> {
/// Start of a container. /// Start of a container.
@ -251,7 +252,7 @@ pub enum Event<'s> {
/// - inline, may only contain inline elements, /// - inline, may only contain inline elements,
/// - block leaf, may only contain inline elements, /// - block leaf, may only contain inline elements,
/// - block container, may contain any block-level elements. /// - block container, may contain any block-level elements.
#[derive(Debug, Clone, PartialEq, Eq, Bake)] #[derive(Debug, Clone, PartialEq, Eq, Bake, Deserialize, Serialize)]
#[databake(path = jotdown)] #[databake(path = jotdown)]
pub enum Container<'s> { pub enum Container<'s> {
/// A blockquote element. /// A blockquote element.
@ -406,7 +407,7 @@ impl<'s> Container<'s> {
} }
/// Alignment of a table column. /// Alignment of a table column.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Bake)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Bake, Deserialize, Serialize)]
#[databake(path = jotdown)] #[databake(path = jotdown)]
pub enum Alignment { pub enum Alignment {
Unspecified, Unspecified,
@ -416,7 +417,7 @@ pub enum Alignment {
} }
/// The type of an inline span link. /// The type of an inline span link.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Bake)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Bake, Deserialize, Serialize)]
#[databake(path = jotdown)] #[databake(path = jotdown)]
pub enum SpanLinkType { pub enum SpanLinkType {
/// E.g. `[text](url)` /// E.g. `[text](url)`
@ -428,7 +429,7 @@ pub enum SpanLinkType {
} }
/// The type of an inline link. /// The type of an inline link.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Bake)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Bake, Deserialize, Serialize)]
#[databake(path = jotdown)] #[databake(path = jotdown)]
pub enum LinkType { pub enum LinkType {
/// E.g. `[text](url)`. /// E.g. `[text](url)`.
@ -440,7 +441,7 @@ pub enum LinkType {
} }
/// The type of a list. /// The type of a list.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Bake)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Bake, Deserialize, Serialize)]
#[databake(path = jotdown)] #[databake(path = jotdown)]
pub enum ListKind { pub enum ListKind {
/// A bullet list. /// A bullet list.
@ -456,7 +457,7 @@ pub enum ListKind {
} }
/// Numbering type of an ordered list. /// Numbering type of an ordered list.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Bake)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Bake, Deserialize, Serialize)]
#[databake(path = jotdown)] #[databake(path = jotdown)]
pub enum OrderedListNumbering { pub enum OrderedListNumbering {
/// Decimal numbering, e.g. `1)`. /// Decimal numbering, e.g. `1)`.
@ -472,7 +473,7 @@ pub enum OrderedListNumbering {
} }
/// Style of an ordered list. /// Style of an ordered list.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Bake)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Bake, Deserialize, Serialize)]
#[databake(path = jotdown)] #[databake(path = jotdown)]
pub enum OrderedListStyle { pub enum OrderedListStyle {
/// Number is followed by a period, e.g. `1.`. /// Number is followed by a period, e.g. `1.`.

View file

@ -6,7 +6,7 @@ default-run = "main"
[dependencies] [dependencies]
afl = "0.11" afl = "0.11"
jotdown = { path = "../../", features = ["deterministic"] } jotdown = { path = "../../", features = ["deterministic", "html", "parser"] }
html5ever = "0.26" html5ever = "0.26"
[[bin]] [[bin]]

View file

@ -5,7 +5,7 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
jotdown = { path = "../.." } jotdown = { path = "../..", features = ["html", "parser"] }
[lib] [lib]
name = "test_html_ref" name = "test_html_ref"

View file

@ -1 +0,0 @@

View file

@ -5,7 +5,7 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
jotdown = { path = "../.." } jotdown = { path = "../..", features = ["html", "parser"] }
[lib] [lib]
name = "test_html_ut" name = "test_html_ut"

View file

@ -1,66 +0,0 @@
use crate::compare;
// Footnote references may appear within a footnote.
#[test]
fn test_1c8325a() {
let src = r##"[^a]
[^a]: a[^b][^c]
[^b]: b
"##;
let expected = r##"<p><a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a></p>
<section role="doc-endnotes">
<hr>
<ol>
<li id="fn1">
<p>a<a id="fnref2" href="#fn2" role="doc-noteref"><sup>2</sup></a><a id="fnref3" href="#fn3" role="doc-noteref"><sup>3</sup></a><a href="#fnref1" role="doc-backlink"></a></p>
</li>
<li id="fn2">
<p>b<a href="#fnref2" role="doc-backlink"></a></p>
</li>
<li id="fn3">
<p><a href="#fnref3" role="doc-backlink"></a></p>
</li>
</ol>
</section>
"##;
compare!(src, expected);
}
// Footnote references in unreferenced footnotes are ignored.
#[test]
fn test_9eab5c8() {
let src = r##"para
[^a]: a[^b][^c]
[^b]: b
"##;
let expected = r##"<p>para</p>
"##;
compare!(src, expected);
}
// Footnotes may appear within footnotes.
#[test]
fn test_041f54c() {
let src = r##"[^b]
[^a]
[^a]: [^b]: inner
"##;
let expected = r##"<p><a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a>
<a id="fnref2" href="#fn2" role="doc-noteref"><sup>2</sup></a></p>
<section role="doc-endnotes">
<hr>
<ol>
<li id="fn1">
<p>inner<a href="#fnref1" role="doc-backlink"></a></p>
</li>
<li id="fn2">
<p><a href="#fnref2" role="doc-backlink"></a></p>
</li>
</ol>
</section>
"##;
compare!(src, expected);
}

View file

@ -1,27 +0,0 @@
use crate::compare;
#[test]
fn test_fefa2dc() {
let src = r##"1. item
para
"##;
let expected = r##"<ol>
<li>
item
</li>
</ol>
<p>para</p>
"##;
compare!(src, expected);
}
// Only single letter alphabetic list markers.
#[test]
fn test_2a0aa95() {
let src = r##"word. Continuing paragraph.
"##;
let expected = r##"<p>word. Continuing paragraph.</p>
"##;
compare!(src, expected);
}

View file

@ -1,3 +0,0 @@
mod footnotes;
mod lists;
mod raw_blocks;

View file

@ -1,24 +0,0 @@
use crate::compare;
#[test]
fn test_bf9dbab() {
let src = r##"```=html
<tag1>
<tag2>
```
paragraph
```=html
</tag2>
</tag1>
```
"##;
let expected = r##"<tag1>
<tag2>
<p>paragraph</p>
</tag2>
</tag1>
"##;
compare!(src, expected);
}