From b136f04bc225380a6aa5daa28075eafd767a4a98 Mon Sep 17 00:00:00 2001
From: Philipp A
Date: Mon, 19 Nov 2018 22:46:33 +0100
Subject: made serializable
---
src/document_tree/extra_attributes.rs | 117 ++++++++++++++++++++++------------
1 file changed, 78 insertions(+), 39 deletions(-)
(limited to 'src/document_tree/extra_attributes.rs')
diff --git a/src/document_tree/extra_attributes.rs b/src/document_tree/extra_attributes.rs
index d73013e..9cd097d 100644
--- a/src/document_tree/extra_attributes.rs
+++ b/src/document_tree/extra_attributes.rs
@@ -1,5 +1,11 @@
use url::Url;
+use serde::{
+ Serialize,
+ Serializer,
+ ser::SerializeStruct,
+};
+
use super::attribute_types::{FixedSpace,ID,NameToken,AlignHV,AlignH,Measure,EnumeratedListType};
pub trait ExtraAttributes {
@@ -8,51 +14,84 @@ pub trait ExtraAttributes {
fn extra_mut(&mut self) -> &mut A;
}
-#[derive(Default,Debug)] pub struct Address { pub space: FixedSpace }
-#[derive(Default,Debug)] pub struct LiteralBlock { pub space: FixedSpace }
-#[derive(Default,Debug)] pub struct DoctestBlock { pub space: FixedSpace }
-#[derive(Default,Debug)] pub struct SubstitutionDefinition { pub ltrim: Option, pub rtrim: Option }
-#[derive(Default,Debug)] pub struct Comment { pub space: FixedSpace }
-#[derive(Default,Debug)] pub struct Target { pub refuri: Option, pub refid: Option, pub refname: Vec, pub anonymous: Option }
-#[derive(Default,Debug)] pub struct Raw { pub space: FixedSpace, pub format: Vec }
-#[derive(Debug)]
-pub struct Image {
- pub align: Option,
- pub uri: Url,
- pub alt: Option,
- pub height: Option,
- pub width: Option,
- pub scale: Option,
+macro_rules! count {
+ () => (0usize);
+ ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));
+}
+
+macro_rules! ser_url {
+ ($self:ident, refuri ) => { $self.refuri.as_ref().map(|uri| uri.to_string()) };
+ ($self:ident, uri ) => { $self.uri.to_string() };
+ ($self:ident, $param:ident) => { $self.$param };
}
+macro_rules! impl_extra {
+ ( $name:ident { $( $param:ident : $type:ty ),* $(,)* } ) => (
+ impl_extra!(
+ #[derive(Default,Debug)]
+ $name { $( $param : $type, )* }
+ );
+ );
+ ( $(#[$attr:meta])+ $name:ident { $( $param:ident : $type:ty ),* $(,)* } ) => (
+ $(#[$attr])+
+ pub struct $name {
+ $( pub $param : $type, )*
+ }
+
+ impl Serialize for $name {
+ fn serialize(&self, serializer: S) -> Result where S: Serializer {
+ #[allow(unused_mut)]
+ let mut state = serializer.serialize_struct(stringify!($name), count!($($param)*))?;
+ $( state.serialize_field(stringify!($param), &ser_url!(self, $param))?; )*
+ state.end()
+ }
+ }
+ );
+}
+
+impl_extra!(Address { space: FixedSpace });
+impl_extra!(LiteralBlock { space: FixedSpace });
+impl_extra!(DoctestBlock { space: FixedSpace });
+impl_extra!(SubstitutionDefinition { ltrim: Option, rtrim: Option });
+impl_extra!(Comment { space: FixedSpace });
+impl_extra!(Target { refuri: Option, refid: Option, refname: Vec, anonymous: Option });
+impl_extra!(Raw { space: FixedSpace, format: Vec });
+impl_extra!(#[derive(Debug)] Image {
+ align: Option,
+ uri: Url,
+ alt: Option,
+ height: Option,
+ width: Option,
+ scale: Option,
+});
+
//bools usually are XML yesorno. “auto” however either exists and is set to something random like “1” or doesn’t exist
-#[derive(Default,Debug)] pub struct BulletList { pub bullet: Option }
-#[derive(Default,Debug)] pub struct EnumeratedList { pub enumtype: Option, pub prefix: Option, pub suffix: Option }
+impl_extra!(BulletList { bullet: Option });
+impl_extra!(EnumeratedList { enumtype: Option, prefix: Option, suffix: Option });
-#[derive(Default,Debug)] pub struct Footnote { pub backrefs: Vec, pub auto: Option }
-#[derive(Default,Debug)] pub struct Citation { pub backrefs: Vec }
-#[derive(Default,Debug)] pub struct SystemMessage { pub backrefs: Vec, pub level: Option, pub line: Option, pub type_: Option }
-#[derive(Default,Debug)] pub struct Figure { pub align: Option, pub width: Option }
-#[derive(Default,Debug)] pub struct Table; //TODO
+impl_extra!(Footnote { backrefs: Vec, auto: Option });
+impl_extra!(Citation { backrefs: Vec });
+impl_extra!(SystemMessage { backrefs: Vec, level: Option, line: Option, type_: Option });
+impl_extra!(Figure { align: Option, width: Option });
+impl_extra!(Table {}); //TODO
-#[derive(Default,Debug)] pub struct OptionArgument { pub delimiter: Option }
+impl_extra!(OptionArgument { delimiter: Option });
-#[derive(Default,Debug)] pub struct Reference { pub name: Option, pub refuri: Option, pub refid: Option, pub refname: Vec }
-#[derive(Default,Debug)] pub struct FootnoteReference { pub refid: Option, pub refname: Vec, pub auto: Option }
-#[derive(Default,Debug)] pub struct CitationReference { pub refid: Option, pub refname: Vec }
-#[derive(Default,Debug)] pub struct SubstitutionReference { pub refname: Vec }
-#[derive(Default,Debug)] pub struct Problematic { pub refid: Option }
+impl_extra!(Reference { name: Option, refuri: Option, refid: Option, refname: Vec });
+impl_extra!(FootnoteReference { refid: Option, refname: Vec, auto: Option });
+impl_extra!(CitationReference { refid: Option, refname: Vec });
+impl_extra!(SubstitutionReference { refname: Vec });
+impl_extra!(Problematic { refid: Option });
//also have non-inline versions. Inline image is no figure child, inline target has content
-#[derive(Default,Debug)] pub struct TargetInline { pub refuri: Option, pub refid: Option, pub refname: Vec, pub anonymous: Option }
-#[derive(Default,Debug)] pub struct RawInline { pub space: FixedSpace, pub format: Vec }
-#[derive(Debug)]
-pub struct ImageInline {
- pub align: Option,
- pub uri: Url,
- pub alt: Option,
- pub height: Option,
- pub width: Option,
- pub scale: Option,
-}
+impl_extra!(TargetInline { refuri: Option, refid: Option, refname: Vec, anonymous: Option });
+impl_extra!(RawInline { space: FixedSpace, format: Vec });
+impl_extra!(#[derive(Debug)] ImageInline {
+ align: Option,
+ uri: Url,
+ alt: Option,
+ height: Option,
+ width: Option,
+ scale: Option,
+});
--
cgit v1.2.3