11use super :: * ;
2+ // use crate::create_header_rid;
23use crate :: documents:: BuildXML ;
4+ use crate :: types:: * ;
35use crate :: xml_builder:: * ;
6+ use crate :: { delegate_getters_to_field, delegate_to_field, Footer , Header } ;
7+ use serde:: ser:: { SerializeStruct , Serializer } ;
8+ use serde:: Serialize ;
49use std:: io:: Write ;
510
6- use serde:: Serialize ;
11+ #[ derive( Debug , Clone , PartialEq ) ]
12+ pub enum SectionChild {
13+ Paragraph ( Box < Paragraph > ) ,
14+ Table ( Box < Table > ) ,
15+ BookmarkStart ( BookmarkStart ) ,
16+ BookmarkEnd ( BookmarkEnd ) ,
17+ CommentStart ( Box < CommentRangeStart > ) ,
18+ CommentEnd ( CommentRangeEnd ) ,
19+ StructuredDataTag ( Box < StructuredDataTag > ) ,
20+ TableOfContents ( Box < TableOfContents > ) ,
21+ }
22+
23+ impl Serialize for SectionChild {
24+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
25+ where
26+ S : Serializer ,
27+ {
28+ match * self {
29+ SectionChild :: Paragraph ( ref p) => {
30+ let mut t = serializer. serialize_struct ( "Paragraph" , 2 ) ?;
31+ t. serialize_field ( "type" , "paragraph" ) ?;
32+ t. serialize_field ( "data" , p) ?;
33+ t. end ( )
34+ }
35+ SectionChild :: Table ( ref c) => {
36+ let mut t = serializer. serialize_struct ( "Table" , 2 ) ?;
37+ t. serialize_field ( "type" , "table" ) ?;
38+ t. serialize_field ( "data" , c) ?;
39+ t. end ( )
40+ }
41+ SectionChild :: BookmarkStart ( ref c) => {
42+ let mut t = serializer. serialize_struct ( "BookmarkStart" , 2 ) ?;
43+ t. serialize_field ( "type" , "bookmarkStart" ) ?;
44+ t. serialize_field ( "data" , c) ?;
45+ t. end ( )
46+ }
47+ SectionChild :: BookmarkEnd ( ref c) => {
48+ let mut t = serializer. serialize_struct ( "BookmarkEnd" , 2 ) ?;
49+ t. serialize_field ( "type" , "bookmarkEnd" ) ?;
50+ t. serialize_field ( "data" , c) ?;
51+ t. end ( )
52+ }
53+ SectionChild :: CommentStart ( ref r) => {
54+ let mut t = serializer. serialize_struct ( "CommentRangeStart" , 2 ) ?;
55+ t. serialize_field ( "type" , "commentRangeStart" ) ?;
56+ t. serialize_field ( "data" , r) ?;
57+ t. end ( )
58+ }
59+ SectionChild :: CommentEnd ( ref r) => {
60+ let mut t = serializer. serialize_struct ( "CommentRangeEnd" , 2 ) ?;
61+ t. serialize_field ( "type" , "commentRangeEnd" ) ?;
62+ t. serialize_field ( "data" , r) ?;
63+ t. end ( )
64+ }
65+ SectionChild :: StructuredDataTag ( ref r) => {
66+ let mut t = serializer. serialize_struct ( "StructuredDataTag" , 2 ) ?;
67+ t. serialize_field ( "type" , "structuredDataTag" ) ?;
68+ t. serialize_field ( "data" , r) ?;
69+ t. end ( )
70+ }
71+ SectionChild :: TableOfContents ( ref r) => {
72+ let mut t = serializer. serialize_struct ( "TableOfContents" , 2 ) ?;
73+ t. serialize_field ( "type" , "tableOfContents" ) ?;
74+ t. serialize_field ( "data" , r) ?;
75+ t. end ( )
76+ }
77+ }
78+ }
79+ }
80+
81+ impl BuildXML for SectionChild {
82+ fn build_to < W : Write > (
83+ & self ,
84+ stream : xml:: writer:: EventWriter < W > ,
85+ ) -> xml:: writer:: Result < xml:: writer:: EventWriter < W > > {
86+ match self {
87+ SectionChild :: Paragraph ( v) => v. build_to ( stream) ,
88+ SectionChild :: Table ( v) => v. build_to ( stream) ,
89+ SectionChild :: BookmarkStart ( v) => v. build_to ( stream) ,
90+ SectionChild :: BookmarkEnd ( v) => v. build_to ( stream) ,
91+ SectionChild :: CommentStart ( v) => v. build_to ( stream) ,
92+ SectionChild :: CommentEnd ( v) => v. build_to ( stream) ,
93+ SectionChild :: StructuredDataTag ( v) => v. build_to ( stream) ,
94+ SectionChild :: TableOfContents ( v) => v. build_to ( stream) ,
95+ }
96+ }
97+ }
798
899#[ derive( Debug , Clone , PartialEq , Serialize ) ]
9100#[ serde( rename_all = "camelCase" ) ]
10101pub struct Section {
11102 property : SectionProperty ,
103+ children : Vec < SectionChild > ,
104+ pub ( crate ) has_numbering : bool ,
12105}
13106
14107impl Section {
15108 pub fn new ( ) -> Section {
16109 Default :: default ( )
17110 }
111+
112+ delegate_to_field ! {
113+ property =>
114+ page_size( size: PageSize ) -> Self ,
115+ page_margin( margin: PageMargin ) -> Self ,
116+ page_orient( o: PageOrientationType ) -> Self ,
117+ doc_grid( doc_grid: DocGrid ) -> Self ,
118+ text_direction( direction: String ) -> Self ,
119+ title_pg( ) -> Self ,
120+ // header(h: Header, rid: &str) -> Self,
121+ // first_header(h: Header, rid: &str) -> Self,
122+ // first_header_without_title_pg(h: Header, rid: &str) -> Self,
123+ // even_header(h: Header, rid: &str) -> Self,
124+ // footer(h: Footer, rid: &str) -> Self,
125+ // first_footer(h: Footer, rid: &str) -> Self,
126+ // first_footer_without_title_pg(h: Footer, rid: &str) -> Self,
127+ // even_footer(h: Footer, rid: &str) -> Self,
128+ page_num_type( h: PageNumType ) -> Self ,
129+ }
130+
131+ delegate_getters_to_field ! {
132+ property =>
133+ get_headers( ) -> Vec <& Header >,
134+ get_footers( ) -> Vec <& Footer >,
135+ }
136+
137+ pub fn add_paragraph ( mut self , p : Paragraph ) -> Self {
138+ if p. has_numbering {
139+ self . has_numbering = true
140+ }
141+ self . children . push ( SectionChild :: Paragraph ( Box :: new ( p) ) ) ;
142+ self
143+ }
144+
145+ pub fn add_table ( mut self , t : Table ) -> Self {
146+ if t. has_numbering {
147+ self . has_numbering = true
148+ }
149+ self . children . push ( SectionChild :: Table ( Box :: new ( t) ) ) ;
150+ self
151+ }
152+
153+ pub fn add_bookmark_start ( mut self , id : usize , name : impl Into < String > ) -> Self {
154+ self . children
155+ . push ( SectionChild :: BookmarkStart ( BookmarkStart :: new ( id, name) ) ) ;
156+ self
157+ }
158+
159+ pub fn add_bookmark_end ( mut self , id : usize ) -> Self {
160+ self . children
161+ . push ( SectionChild :: BookmarkEnd ( BookmarkEnd :: new ( id) ) ) ;
162+ self
163+ }
164+
165+ pub fn add_comment_start ( mut self , comment : Comment ) -> Self {
166+ self . children . push ( SectionChild :: CommentStart ( Box :: new (
167+ CommentRangeStart :: new ( comment) ,
168+ ) ) ) ;
169+ self
170+ }
171+
172+ pub fn add_comment_end ( mut self , id : usize ) -> Self {
173+ self . children
174+ . push ( SectionChild :: CommentEnd ( CommentRangeEnd :: new ( id) ) ) ;
175+ self
176+ }
177+
178+ // TODO: inject count or create temp header
179+ // pub fn header(mut self, header: Header) -> Self {
180+ // self.property = self.property.header(header, &create_header_rid(count));
181+ // self
182+ // }
18183}
19184
20185impl Default for Section {
21186 fn default ( ) -> Self {
22187 Self {
23188 property : SectionProperty :: new ( ) ,
189+ children : vec ! [ ] ,
190+ has_numbering : false ,
24191 }
25192 }
26193}
@@ -32,6 +199,7 @@ impl BuildXML for Section {
32199 ) -> xml:: writer:: Result < xml:: writer:: EventWriter < W > > {
33200 let id = crate :: generate_para_id ( ) ;
34201 XMLBuilder :: from ( stream)
202+ . add_children ( & self . children ) ?
35203 . open_paragraph ( & id) ?
36204 . open_paragraph_property ( ) ?
37205 . add_child ( & self . property ) ?
@@ -58,4 +226,15 @@ mod tests {
58226 r#"<w:p w14:paraId="12345678"><w:pPr><w:sectPr><w:pgSz w:w="11906" w:h="16838" /><w:pgMar w:top="1985" w:right="1701" w:bottom="1701" w:left="1701" w:header="851" w:footer="992" w:gutter="0" /><w:cols w:space="425" w:num="1" /></w:sectPr></w:pPr></w:p>"#
59227 ) ;
60228 }
229+
230+ #[ test]
231+ fn test_section_with_paragraph ( ) {
232+ let c =
233+ Section :: new ( ) . add_paragraph ( Paragraph :: new ( ) . add_run ( Run :: new ( ) . add_text ( "Hello" ) ) ) ;
234+ let b = c. build ( ) ;
235+ assert_eq ! (
236+ str :: from_utf8( & b) . unwrap( ) ,
237+ r#"<w:p w14:paraId="12345678"><w:pPr><w:rPr /></w:pPr><w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r></w:p><w:p w14:paraId="12345678"><w:pPr><w:sectPr><w:pgSz w:w="11906" w:h="16838" /><w:pgMar w:top="1985" w:right="1701" w:bottom="1701" w:left="1701" w:header="851" w:footer="992" w:gutter="0" /><w:cols w:space="425" w:num="1" /></w:sectPr></w:pPr></w:p>"#
238+ ) ;
239+ }
61240}
0 commit comments