1
- use crate :: { ParseItem , PreprocessorId , PreprocessorOutput } ;
2
- use std:: { collections:: HashMap , path:: PathBuf , sync:: Mutex } ;
1
+ use crate :: { DocBuilder , ParseItem , PreprocessorId , PreprocessorOutput } ;
2
+ use std:: {
3
+ collections:: HashMap ,
4
+ path:: { Path , PathBuf } ,
5
+ slice:: IterMut ,
6
+ sync:: Mutex ,
7
+ } ;
3
8
4
9
/// The wrapper around the [ParseItem] containing additional
5
10
/// information the original item and extra context for outputting it.
@@ -62,6 +67,15 @@ impl Document {
62
67
let context = self . context . lock ( ) . expect ( "failed to lock context" ) ;
63
68
context. get ( & id) . cloned ( )
64
69
}
70
+
71
+ fn try_relative_output_path ( & self ) -> Option < & Path > {
72
+ self . target_path . strip_prefix ( & self . out_target_dir ) . ok ( ) ?. strip_prefix ( DocBuilder :: SRC ) . ok ( )
73
+ }
74
+
75
+ /// Returns the relative path of the document output.
76
+ pub fn relative_output_path ( & self ) -> & Path {
77
+ self . try_relative_output_path ( ) . unwrap_or ( self . target_path . as_path ( ) )
78
+ }
65
79
}
66
80
67
81
/// The content of the document.
@@ -73,6 +87,100 @@ pub enum DocumentContent {
73
87
OverloadedFunctions ( Vec < ParseItem > ) ,
74
88
}
75
89
90
+ impl DocumentContent {
91
+ pub ( crate ) fn len ( & self ) -> usize {
92
+ match self {
93
+ DocumentContent :: Empty => 0 ,
94
+ DocumentContent :: Single ( _) => 1 ,
95
+ DocumentContent :: Constants ( items) => items. len ( ) ,
96
+ DocumentContent :: OverloadedFunctions ( items) => items. len ( ) ,
97
+ }
98
+ }
99
+
100
+ pub ( crate ) fn get_mut ( & mut self , index : usize ) -> Option < & mut ParseItem > {
101
+ match self {
102
+ DocumentContent :: Empty => None ,
103
+ DocumentContent :: Single ( item) => {
104
+ if index == 0 {
105
+ Some ( item)
106
+ } else {
107
+ None
108
+ }
109
+ }
110
+ DocumentContent :: Constants ( items) => items. get_mut ( index) ,
111
+ DocumentContent :: OverloadedFunctions ( items) => items. get_mut ( index) ,
112
+ }
113
+ }
114
+
115
+ pub fn iter_items ( & self ) -> ParseItemIter < ' _ > {
116
+ match self {
117
+ DocumentContent :: Empty => ParseItemIter { next : None , other : None } ,
118
+ DocumentContent :: Single ( item) => ParseItemIter { next : Some ( item) , other : None } ,
119
+ DocumentContent :: Constants ( items) => {
120
+ ParseItemIter { next : None , other : Some ( items. iter ( ) ) }
121
+ }
122
+ DocumentContent :: OverloadedFunctions ( items) => {
123
+ ParseItemIter { next : None , other : Some ( items. iter ( ) ) }
124
+ }
125
+ }
126
+ }
127
+
128
+ pub fn iter_items_mut ( & mut self ) -> ParseItemIterMut < ' _ > {
129
+ match self {
130
+ DocumentContent :: Empty => ParseItemIterMut { next : None , other : None } ,
131
+ DocumentContent :: Single ( item) => ParseItemIterMut { next : Some ( item) , other : None } ,
132
+ DocumentContent :: Constants ( items) => {
133
+ ParseItemIterMut { next : None , other : Some ( items. iter_mut ( ) ) }
134
+ }
135
+ DocumentContent :: OverloadedFunctions ( items) => {
136
+ ParseItemIterMut { next : None , other : Some ( items. iter_mut ( ) ) }
137
+ }
138
+ }
139
+ }
140
+ }
141
+
142
+ #[ derive( Debug ) ]
143
+ pub struct ParseItemIter < ' a > {
144
+ next : Option < & ' a ParseItem > ,
145
+ other : Option < std:: slice:: Iter < ' a , ParseItem > > ,
146
+ }
147
+
148
+ impl < ' a > Iterator for ParseItemIter < ' a > {
149
+ type Item = & ' a ParseItem ;
150
+
151
+ fn next ( & mut self ) -> Option < Self :: Item > {
152
+ if let Some ( next) = self . next . take ( ) {
153
+ return Some ( next)
154
+ }
155
+ if let Some ( other) = self . other . as_mut ( ) {
156
+ return other. next ( )
157
+ }
158
+
159
+ None
160
+ }
161
+ }
162
+
163
+ #[ derive( Debug ) ]
164
+ pub struct ParseItemIterMut < ' a > {
165
+ next : Option < & ' a mut ParseItem > ,
166
+ other : Option < IterMut < ' a , ParseItem > > ,
167
+ }
168
+
169
+ impl < ' a > Iterator for ParseItemIterMut < ' a > {
170
+ type Item = & ' a mut ParseItem ;
171
+
172
+ fn next ( & mut self ) -> Option < Self :: Item > {
173
+ if let Some ( next) = self . next . take ( ) {
174
+ return Some ( next)
175
+ }
176
+ if let Some ( other) = self . other . as_mut ( ) {
177
+ return other. next ( )
178
+ }
179
+
180
+ None
181
+ }
182
+ }
183
+
76
184
/// Read the preprocessor output variant from document context.
77
185
/// Returns [None] if there is no output.
78
186
macro_rules! read_context {
0 commit comments