diff --git a/Cargo.toml b/Cargo.toml index 7e9e541..7f82163 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,8 @@ all-features = true travis-ci = { repository = "PoiScript/orgize" } [features] -default = ["serde"] +default = ["ser"] +ser = ["serde", "serde_indextree"] [dependencies] bytecount = "0.5.1" @@ -26,6 +27,7 @@ jetscii = "0.4.4" memchr = "2.2.1" nom = "5.0.0" serde = { version = "1.0.98", optional = true, features = ["derive"] } +serde_indextree = { version = "0.1.0", optional = true } [dev-dependencies] lazy_static = "1.3.0" diff --git a/README.md b/README.md index c3a55bc..cc270b4 100644 --- a/README.md +++ b/README.md @@ -195,7 +195,7 @@ println!("{}", to_string(&org).unwrap()); By now, orgize provides two features: -+ `serde`: adds the ability to serialize `Org` and other elements using `serde`, enabled by default. ++ `ser`: adds the ability to serialize `Org` and other elements using `serde`, enabled by default. + `chrono`: adds the ability to convert `Datetime` into `chrono` structs, disabled by default. diff --git a/src/elements/block.rs b/src/elements/block.rs index 375c75c..8bcec09 100644 --- a/src/elements/block.rs +++ b/src/elements/block.rs @@ -64,7 +64,7 @@ fn parse() { #[derive(Debug)] #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] pub struct SpecialBlock<'a> { pub parameters: Option<&'a str>, pub name: &'a str, @@ -72,28 +72,28 @@ pub struct SpecialBlock<'a> { #[derive(Debug)] #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] pub struct QuoteBlock<'a> { pub parameters: Option<&'a str>, } #[derive(Debug)] #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] pub struct CenterBlock<'a> { pub parameters: Option<&'a str>, } #[derive(Debug)] #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] pub struct VerseBlock<'a> { pub parameters: Option<&'a str>, } #[derive(Debug)] #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] pub struct CommentBlock<'a> { pub data: Option<&'a str>, pub contents: &'a str, @@ -101,7 +101,7 @@ pub struct CommentBlock<'a> { #[derive(Debug)] #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] pub struct ExampleBlock<'a> { pub data: Option<&'a str>, pub contents: &'a str, @@ -109,7 +109,7 @@ pub struct ExampleBlock<'a> { #[derive(Debug)] #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] pub struct ExportBlock<'a> { pub data: &'a str, pub contents: &'a str, @@ -117,7 +117,7 @@ pub struct ExportBlock<'a> { #[derive(Debug)] #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] pub struct SourceBlock<'a> { pub contents: &'a str, pub language: &'a str, diff --git a/src/elements/clock.rs b/src/elements/clock.rs index e2d1c0a..7fbbaab 100644 --- a/src/elements/clock.rs +++ b/src/elements/clock.rs @@ -13,26 +13,26 @@ use crate::parsers::eol; /// /// there are two types of clock: *closed* clock and *running* clock. #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[cfg_attr(feature = "serde", serde(untagged))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", serde(untagged))] #[derive(Debug)] pub enum Clock<'a> { /// closed Clock Closed { start: Datetime<'a>, end: Datetime<'a>, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] repeater: Option<&'a str>, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] delay: Option<&'a str>, duration: &'a str, }, /// running Clock Running { start: Datetime<'a>, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] repeater: Option<&'a str>, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] delay: Option<&'a str>, }, } diff --git a/src/elements/cookie.rs b/src/elements/cookie.rs index 6cfbbce..f02607b 100644 --- a/src/elements/cookie.rs +++ b/src/elements/cookie.rs @@ -8,7 +8,7 @@ use nom::{ }; #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct Cookie<'a> { pub value: &'a str, diff --git a/src/elements/drawer.rs b/src/elements/drawer.rs index 01e52c2..cc764e3 100644 --- a/src/elements/drawer.rs +++ b/src/elements/drawer.rs @@ -7,7 +7,7 @@ use nom::{ }; #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct Drawer<'a> { pub name: &'a str, diff --git a/src/elements/dyn_block.rs b/src/elements/dyn_block.rs index 72ca856..65c2744 100644 --- a/src/elements/dyn_block.rs +++ b/src/elements/dyn_block.rs @@ -8,11 +8,11 @@ use nom::{ }; #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct DynBlock<'a> { pub block_name: &'a str, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] pub arguments: Option<&'a str>, } diff --git a/src/elements/fn_def.rs b/src/elements/fn_def.rs index 8d0ed1e..a5e03c3 100644 --- a/src/elements/fn_def.rs +++ b/src/elements/fn_def.rs @@ -6,7 +6,7 @@ use nom::{ }; #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct FnDef<'a> { pub label: &'a str, diff --git a/src/elements/fn_ref.rs b/src/elements/fn_ref.rs index 8e11f3e..eb6e2db 100644 --- a/src/elements/fn_ref.rs +++ b/src/elements/fn_ref.rs @@ -9,11 +9,11 @@ use nom::{ }; #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct FnRef<'a> { pub label: &'a str, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] pub definition: Option<&'a str>, } diff --git a/src/elements/inline_call.rs b/src/elements/inline_call.rs index afb8cf9..fc51ee6 100644 --- a/src/elements/inline_call.rs +++ b/src/elements/inline_call.rs @@ -8,14 +8,14 @@ use nom::{ use crate::elements::Element; #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct InlineCall<'a> { pub name: &'a str, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] pub inside_header: Option<&'a str>, pub arguments: &'a str, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] pub end_header: Option<&'a str>, } diff --git a/src/elements/inline_src.rs b/src/elements/inline_src.rs index 18d7c0f..046df20 100644 --- a/src/elements/inline_src.rs +++ b/src/elements/inline_src.rs @@ -8,11 +8,11 @@ use nom::{ use crate::elements::Element; #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct InlineSrc<'a> { pub lang: &'a str, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] pub options: Option<&'a str>, pub body: &'a str, } diff --git a/src/elements/keyword.rs b/src/elements/keyword.rs index 7b61d25..810d603 100644 --- a/src/elements/keyword.rs +++ b/src/elements/keyword.rs @@ -9,17 +9,17 @@ use crate::elements::Element; use crate::parsers::take_until_eol; #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct Keyword<'a> { pub key: &'a str, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] pub optional: Option<&'a str>, pub value: &'a str, } #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct BabelCall<'a> { pub value: &'a str, diff --git a/src/elements/link.rs b/src/elements/link.rs index 454b24d..d202ed6 100644 --- a/src/elements/link.rs +++ b/src/elements/link.rs @@ -8,11 +8,11 @@ use nom::{ use crate::elements::Element; #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct Link<'a> { pub path: &'a str, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] pub desc: Option<&'a str>, } diff --git a/src/elements/list.rs b/src/elements/list.rs index 83ba1dd..d945656 100644 --- a/src/elements/list.rs +++ b/src/elements/list.rs @@ -2,7 +2,7 @@ use memchr::memchr_iter; use std::iter::once; #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct List { pub indent: usize, @@ -62,7 +62,7 @@ impl List { } #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct ListItem<'a> { pub bullet: &'a str, diff --git a/src/elements/macros.rs b/src/elements/macros.rs index e62e34d..7830ce6 100644 --- a/src/elements/macros.rs +++ b/src/elements/macros.rs @@ -8,11 +8,11 @@ use nom::{ use crate::elements::Element; #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct Macros<'a> { pub name: &'a str, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] pub arguments: Option<&'a str>, } diff --git a/src/elements/mod.rs b/src/elements/mod.rs index 7f54147..2bd0637 100644 --- a/src/elements/mod.rs +++ b/src/elements/mod.rs @@ -56,8 +56,8 @@ pub use self::{ /// Org-mode element enum #[derive(Debug)] #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[cfg_attr(feature = "serde", serde(tag = "type", rename_all = "kebab-case"))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", serde(tag = "type", rename_all = "kebab-case"))] pub enum Element<'a> { SpecialBlock(SpecialBlock<'a>), QuoteBlock(QuoteBlock<'a>), diff --git a/src/elements/planning.rs b/src/elements/planning.rs index a744b56..340ad42 100644 --- a/src/elements/planning.rs +++ b/src/elements/planning.rs @@ -4,17 +4,17 @@ use crate::elements::Timestamp; /// palnning elements #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct Planning<'a> { /// the date when the task should be done - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] pub deadline: Option>, /// the date when you should start working on the task - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] pub scheduled: Option>, /// the date when the task is closed - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] pub closed: Option>, } diff --git a/src/elements/radio_target.rs b/src/elements/radio_target.rs index 7f09ea7..105e7ad 100644 --- a/src/elements/radio_target.rs +++ b/src/elements/radio_target.rs @@ -9,7 +9,7 @@ use crate::elements::Element; // TODO: text-markup, entities, latex-fragments, subscript and superscript #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct RadioTarget; diff --git a/src/elements/snippet.rs b/src/elements/snippet.rs index cc55266..3708fcc 100644 --- a/src/elements/snippet.rs +++ b/src/elements/snippet.rs @@ -7,7 +7,7 @@ use nom::{ use crate::elements::Element; #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct Snippet<'a> { pub name: &'a str, diff --git a/src/elements/table.rs b/src/elements/table.rs index 6eacffc..815100f 100644 --- a/src/elements/table.rs +++ b/src/elements/table.rs @@ -1,19 +1,19 @@ #[derive(Debug)] #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[cfg_attr(feature = "serde", serde(tag = "table_type"))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", serde(tag = "table_type"))] pub enum Table<'a> { - #[cfg_attr(feature = "serde", serde(rename = "org"))] + #[cfg_attr(feature = "ser", serde(rename = "org"))] Org { tblfm: Option<&'a str> }, - #[cfg_attr(feature = "serde", serde(rename = "table.el"))] + #[cfg_attr(feature = "ser", serde(rename = "table.el"))] TableEl { value: &'a str }, } #[derive(Debug)] #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[cfg_attr( - feature = "serde", + feature = "ser", serde(tag = "table_row_type", rename_all = "kebab-case") )] pub enum TableRow { diff --git a/src/elements/target.rs b/src/elements/target.rs index 129f59b..7eb9d9e 100644 --- a/src/elements/target.rs +++ b/src/elements/target.rs @@ -8,7 +8,7 @@ use nom::{ use crate::elements::Element; #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct Target<'a> { pub target: &'a str, diff --git a/src/elements/timestamp.rs b/src/elements/timestamp.rs index a8e4d4f..345f7a4 100644 --- a/src/elements/timestamp.rs +++ b/src/elements/timestamp.rs @@ -15,16 +15,16 @@ use nom::{ /// ``` /// #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug, Clone)] pub struct Datetime<'a> { pub year: u16, pub month: u8, pub day: u8, pub dayname: &'a str, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] pub hour: Option, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] pub minute: Option, } @@ -104,38 +104,41 @@ mod chrono { } #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[cfg_attr(feature = "serde", serde(tag = "timestamp_type", rename_all = "kebab-case"))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] +#[cfg_attr( + feature = "ser", + serde(tag = "timestamp_type", rename_all = "kebab-case") +)] #[derive(Debug)] pub enum Timestamp<'a> { Active { start: Datetime<'a>, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] repeater: Option<&'a str>, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] delay: Option<&'a str>, }, Inactive { start: Datetime<'a>, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] repeater: Option<&'a str>, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] delay: Option<&'a str>, }, ActiveRange { start: Datetime<'a>, end: Datetime<'a>, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] repeater: Option<&'a str>, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] delay: Option<&'a str>, }, InactiveRange { start: Datetime<'a>, end: Datetime<'a>, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] repeater: Option<&'a str>, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] delay: Option<&'a str>, }, Diary { @@ -261,7 +264,7 @@ impl Timestamp<'_> { // TODO // #[cfg_attr(test, derive(PartialEq))] -// #[cfg_attr(feature = "serde", derive(serde::Serialize))] +// #[cfg_attr(feature = "ser", derive(serde::Serialize))] // #[derive(Debug, Copy, Clone)] // pub enum RepeaterType { // Cumulate, @@ -270,7 +273,7 @@ impl Timestamp<'_> { // } // #[cfg_attr(test, derive(PartialEq))] -// #[cfg_attr(feature = "serde", derive(serde::Serialize))] +// #[cfg_attr(feature = "ser", derive(serde::Serialize))] // #[derive(Debug, Copy, Clone)] // pub enum DelayType { // All, @@ -278,7 +281,7 @@ impl Timestamp<'_> { // } // #[cfg_attr(test, derive(PartialEq))] -// #[cfg_attr(feature = "serde", derive(serde::Serialize))] +// #[cfg_attr(feature = "ser", derive(serde::Serialize))] // #[derive(Debug, Copy, Clone)] // pub enum TimeUnit { // Hour, @@ -289,7 +292,7 @@ impl Timestamp<'_> { // } // #[cfg_attr(test, derive(PartialEq))] -// #[cfg_attr(feature = "serde", derive(serde::Serialize))] +// #[cfg_attr(feature = "ser", derive(serde::Serialize))] // #[derive(Debug, Copy, Clone)] // pub struct Repeater { // pub ty: RepeaterType, @@ -298,7 +301,7 @@ impl Timestamp<'_> { // } // #[cfg_attr(test, derive(PartialEq))] -// #[cfg_attr(feature = "serde", derive(serde::Serialize))] +// #[cfg_attr(feature = "ser", derive(serde::Serialize))] // #[derive(Debug, Copy, Clone)] // pub struct Delay { // pub ty: DelayType, diff --git a/src/elements/title.rs b/src/elements/title.rs index 2e1b5c0..814dcb3 100644 --- a/src/elements/title.rs +++ b/src/elements/title.rs @@ -17,24 +17,24 @@ use crate::elements::{Drawer, Planning}; use crate::parsers::{skip_empty_lines, take_one_word, take_until_eol}; #[cfg_attr(test, derive(PartialEq))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "ser", derive(serde::Serialize))] #[derive(Debug)] pub struct Title<'a> { /// headline level, number of stars pub level: usize, /// priority cookie - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] pub priority: Option, /// headline tags, including the sparated colons - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Vec::is_empty"))] pub tags: Vec<&'a str>, /// headline keyword - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] pub keyword: Option<&'a str>, pub raw: &'a str, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))] pub planning: Option>>, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "HashMap::is_empty"))] + #[cfg_attr(feature = "ser", serde(skip_serializing_if = "HashMap::is_empty"))] pub properties: HashMap<&'a str, &'a str>, } diff --git a/src/lib.rs b/src/lib.rs index c012167..0c2773d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -206,7 +206,7 @@ //! //! By now, orgize provides two features: //! -//! + `serde`: adds the ability to serialize `Org` and other elements using `serde`, enabled by default. +//! + `ser`: adds the ability to serialize `Org` and other elements using `serde`, enabled by default. //! //! + `chrono`: adds the ability to convert `Datetime` into `chrono` structs, disabled by default. //! @@ -221,8 +221,6 @@ pub mod elements; pub mod export; mod org; mod parsers; -#[cfg(feature = "serde")] -mod serde; pub use config::ParseConfig; pub use elements::Element; diff --git a/src/org.rs b/src/org.rs index f41fd74..472da2e 100644 --- a/src/org.rs +++ b/src/org.rs @@ -7,8 +7,8 @@ use crate::export::*; use crate::parsers::*; pub struct Org<'a> { - pub(crate) arena: Arena>, - pub(crate) document: NodeId, + arena: Arena>, + document: NodeId, } #[derive(Debug)] @@ -108,3 +108,15 @@ impl Org<'_> { Ok(()) } } + +#[cfg(feature = "ser")] +use serde::{ser::Serializer, Serialize}; + +#[cfg(feature = "ser")] +impl Serialize for Org<'_> { + fn serialize(&self, serializer: S) -> Result { + use serde_indextree::Node; + + serializer.serialize_newtype_struct("Node", &Node::new(self.document, &self.arena)) + } +} diff --git a/src/serde.rs b/src/serde.rs deleted file mode 100644 index 7210f26..0000000 --- a/src/serde.rs +++ /dev/null @@ -1,48 +0,0 @@ -use indextree::{Arena, NodeId}; -use serde::ser::{SerializeSeq, Serializer}; -use serde::Serialize; - -use crate::elements::Element; -use crate::org::Org; - -impl Serialize for Org<'_> { - fn serialize(&self, serializer: S) -> Result { - serializer - .serialize_newtype_struct("ElementNode", &ElementNode::new(self.document, &self.arena)) - } -} - -#[derive(Serialize)] -struct ElementNode<'a> { - #[serde(flatten)] - element: &'a Element<'a>, - #[serde(skip_serializing_if = "Option::is_none")] - children: Option>, -} - -impl<'a> ElementNode<'a> { - fn new(node_id: NodeId, arena: &'a Arena>) -> Self { - let node = &arena[node_id]; - ElementNode { - element: &node.data, - children: node - .first_child() - .map(|first| ElementChildrenNode { first, arena }), - } - } -} - -struct ElementChildrenNode<'a> { - first: NodeId, - arena: &'a Arena>, -} - -impl Serialize for ElementChildrenNode<'_> { - fn serialize(&self, serializer: S) -> Result { - let mut seq = serializer.serialize_seq(None)?; - for node in self.first.following_siblings(&self.arena) { - seq.serialize_element(&ElementNode::new(node, &self.arena))?; - } - seq.end() - } -}