From 626cc2d747f198ba94bac241a872927968f50431 Mon Sep 17 00:00:00 2001 From: Philipp A Date: Sat, 30 Mar 2019 18:02:40 +0100 Subject: Skip empty attributes --- src/document_tree/attribute_types.rs | 41 +++++++++++++++++++++++++++++++++++ src/document_tree/elements.rs | 12 ++++++---- src/document_tree/extra_attributes.rs | 12 ++-------- 3 files changed, 51 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/document_tree/attribute_types.rs b/src/document_tree/attribute_types.rs index 400c59e..1648c18 100644 --- a/src/document_tree/attribute_types.rs +++ b/src/document_tree/attribute_types.rs @@ -4,6 +4,8 @@ use failure::{Error,bail,format_err}; use serde_derive::Serialize; use regex::Regex; +use crate::target; + #[derive(Debug,PartialEq,Serialize)] pub enum EnumeratedListType { Arabic, @@ -96,3 +98,42 @@ mod test { let _d: Measure = "1.pc".parse().unwrap(); } } + +pub(crate) trait CanBeEmpty { + fn is_empty(&self) -> bool; +} + +/* Specialization necessary +impl CanBeEmpty for T { + fn is_empty(&self) -> bool { false } +} +*/ +macro_rules! impl_cannot_be_empty { + ($t:ty) => { + impl CanBeEmpty for $t { + fn is_empty(&self) -> bool { false } + } + }; + ($t:ty, $($ts:ty),*) => { + impl_cannot_be_empty!($t); + impl_cannot_be_empty!($($ts),*); + }; +} +impl_cannot_be_empty!(target::Target); + +impl CanBeEmpty for Option { + fn is_empty(&self) -> bool { self.is_none() } +} + +impl CanBeEmpty for Vec { + fn is_empty(&self) -> bool { self.is_empty() } +} + +impl CanBeEmpty for bool { + fn is_empty(&self) -> bool { !self } +} + +impl CanBeEmpty for FixedSpace { + fn is_empty(&self) -> bool { self == &FixedSpace::default() } +} + diff --git a/src/document_tree/elements.rs b/src/document_tree/elements.rs index 52b1f5b..fe5a498 100644 --- a/src/document_tree/elements.rs +++ b/src/document_tree/elements.rs @@ -1,7 +1,7 @@ use serde_derive::Serialize; use crate::target; -use super::attribute_types::{ID,NameToken}; +use super::attribute_types::{CanBeEmpty,ID,NameToken}; use super::extra_attributes::{self,ExtraAttributes}; use super::element_categories::*; @@ -28,9 +28,13 @@ pub trait Element { #[derive(Debug,Default,PartialEq,Serialize)] pub struct CommonAttributes { - ids: Vec, - names: Vec, - source: Option, + #[serde(skip_serializing_if = "CanBeEmpty::is_empty")] + ids: Vec, + #[serde(skip_serializing_if = "CanBeEmpty::is_empty")] + names: Vec, + #[serde(skip_serializing_if = "CanBeEmpty::is_empty")] + source: Option, + #[serde(skip_serializing_if = "CanBeEmpty::is_empty")] classes: Vec, //TODO: dupnames } diff --git a/src/document_tree/extra_attributes.rs b/src/document_tree/extra_attributes.rs index 0708080..d73cdec 100644 --- a/src/document_tree/extra_attributes.rs +++ b/src/document_tree/extra_attributes.rs @@ -1,7 +1,7 @@ use serde_derive::Serialize; use crate::target; -use super::attribute_types::{FixedSpace,ID,NameToken,AlignHV,AlignH,Measure,EnumeratedListType}; +use super::attribute_types::{CanBeEmpty,FixedSpace,ID,NameToken,AlignHV,AlignH,Measure,EnumeratedListType}; pub trait ExtraAttributes { fn with_extra(extra: A) -> Self; @@ -9,14 +9,6 @@ pub trait ExtraAttributes { fn extra_mut(&mut self) -> &mut A; } -/* -macro_rules! skip { - (Option<$type:ty>) => { #[serde(skip_serializing_if = "Option::is_none")] }; - (Vec <$type:ty>) => { #[serde(skip_serializing_if = "Vec::is_empty" )] }; - (bool ) => { #[serde(skip_serializing_if = "Not::not" )] }; -} -*/ - macro_rules! impl_extra { ( $name:ident { $( $(#[$pattr:meta])* $param:ident : $type:ty ),* $(,)* } ) => ( impl_extra!( @@ -28,7 +20,7 @@ macro_rules! impl_extra { $(#[$attr])+ pub struct $name { $( $(#[$pattr])* - // skip!($type) + #[serde(skip_serializing_if = "CanBeEmpty::is_empty")] pub $param : $type, )* } ); -- cgit v1.2.3