redsnow 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +3 -1
  3. data/README.md +12 -0
  4. data/ext/snowcrash/bin/snowcrash +0 -0
  5. data/ext/snowcrash/ext/markdown-parser/ext/sundown/src/markdown.c +5 -2
  6. data/ext/snowcrash/snowcrash.gyp +7 -2
  7. data/ext/snowcrash/src/ActionParser.h +141 -81
  8. data/ext/snowcrash/src/AssetParser.h +19 -11
  9. data/ext/snowcrash/src/Blueprint.h +44 -14
  10. data/ext/snowcrash/src/BlueprintParser.h +65 -51
  11. data/ext/snowcrash/src/BlueprintSourcemap.h +254 -0
  12. data/ext/snowcrash/src/BlueprintUtility.h +3 -24
  13. data/ext/snowcrash/src/CBlueprint.cc +40 -31
  14. data/ext/snowcrash/src/CBlueprint.h +54 -58
  15. data/ext/snowcrash/src/CBlueprintSourcemap.cc +620 -0
  16. data/ext/snowcrash/src/CBlueprintSourcemap.h +342 -0
  17. data/ext/snowcrash/src/CSourceAnnotation.cc +14 -0
  18. data/ext/snowcrash/src/CodeBlockUtility.h +42 -5
  19. data/ext/snowcrash/src/HeadersParser.h +84 -42
  20. data/ext/snowcrash/src/ParameterParser.h +110 -68
  21. data/ext/snowcrash/src/ParametersParser.h +26 -28
  22. data/ext/snowcrash/src/PayloadParser.h +164 -83
  23. data/ext/snowcrash/src/ResourceGroupParser.h +35 -41
  24. data/ext/snowcrash/src/ResourceParser.h +142 -97
  25. data/ext/snowcrash/src/SectionParser.h +15 -14
  26. data/ext/snowcrash/src/SectionParserData.h +11 -2
  27. data/ext/snowcrash/src/SectionProcessor.h +42 -18
  28. data/ext/snowcrash/src/Serialize.cc +2 -0
  29. data/ext/snowcrash/src/Serialize.h +3 -1
  30. data/ext/snowcrash/src/SerializeJSON.cc +608 -16
  31. data/ext/snowcrash/src/SerializeJSON.h +4 -1
  32. data/ext/snowcrash/src/SerializeYAML.cc +367 -19
  33. data/ext/snowcrash/src/SerializeYAML.h +4 -1
  34. data/ext/snowcrash/src/SymbolTable.h +12 -1
  35. data/ext/snowcrash/src/ValuesParser.h +12 -11
  36. data/ext/snowcrash/src/Version.h +1 -1
  37. data/ext/snowcrash/src/csnowcrash.cc +7 -3
  38. data/ext/snowcrash/src/csnowcrash.h +4 -2
  39. data/ext/snowcrash/src/snowcrash.cc +10 -11
  40. data/ext/snowcrash/src/snowcrash.h +3 -3
  41. data/ext/snowcrash/src/snowcrash/snowcrash.cc +38 -8
  42. data/ext/snowcrash/tools/homebrew/snowcrash.rb +1 -1
  43. data/lib/redsnow.rb +41 -2
  44. data/lib/redsnow/binding.rb +93 -8
  45. data/lib/redsnow/blueprint.rb +48 -25
  46. data/lib/redsnow/parseresult.rb +9 -2
  47. data/lib/redsnow/sourcemap.rb +369 -0
  48. data/lib/redsnow/version.rb +1 -1
  49. data/test/fixtures/sample-api-ast.json +1 -1
  50. data/test/fixtures/sample-api-sourcemap.json +169 -0
  51. data/test/redsnow_binding_test.rb +19 -2
  52. data/test/redsnow_options_test.rb +42 -0
  53. data/test/redsnow_parseresult_test.rb +5 -1
  54. data/test/redsnow_test.rb +5 -0
  55. metadata +11 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a54dde4bcbcf36bbd37d5f863e51b16bb247232a
4
- data.tar.gz: 79fecb4a236ff45e54942a3da1f871088f9aba6c
3
+ metadata.gz: ee23a2d43da39feb6ca4e0238652fb4ab3233975
4
+ data.tar.gz: b9f182cffddcd81c49b515c8b033f4d84f7a3f64
5
5
  SHA512:
6
- metadata.gz: 9854dd4d2376d9fe8edc14791390d86a60ec973790809400c21820cf429f6fa9e08b81e13bbe1b9e21c17a7308d105d8b68f70f5d8763a6ba3ddf734bacd5657
7
- data.tar.gz: bc9ed83bc8b1e0fe7a339b7c282c08740254d75490c92ec4a05e48b00134490f5b90ce095e8715ce96a2780fac71cd557463a09be7380fc83b3b51ac2e31b416
6
+ metadata.gz: 0d6f68de2038028753baffa195aeea9e85d4cf020a3013a330259ca467009b1af0423642bd2464278198a50002edaae6752c8a16d78fe0a431f23fbfb819f848
7
+ data.tar.gz: dc19e0bee08bb8dfc73433a916c2155674ffd048ac231d38aebb4a947e8ab66619f1178659ccc9ebddff4b5428dd45101985f4a91d45379bd36a710e6986c05f
data/CHANGELOG.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Changelog
2
+ - 0.2.1
3
+ - Support for source maps [Snow Crash v0.15.0](https://github.com/apiaryio/snowcrash/releases/tag/v0.15.0) and [AST Serialization Format 2.1](https://github.com/apiaryio/api-blueprint-ast/releases/tag/v2.1).
2
4
  - 0.2.0
3
- - New Parser Architecture [Snow Crash v0.14.0](https://github.com/apiaryio/snowcrash/releases)
5
+ - New Parser Architecture [Snow Crash v0.14.0](https://github.com/apiaryio/snowcrash/releases/tag/v0.14.0)
4
6
  - 0.1.6
5
7
  - Fixing problem with submodules in Gem install [IS#25](https://github.com/apiaryio/redsnow/issues/25)
6
8
  - 0.1.5
data/README.md CHANGED
@@ -24,6 +24,18 @@ result = RedSnow::parse('# My API')
24
24
  puts result.ast.name
25
25
  ```
26
26
 
27
+ ## Parsing options
28
+
29
+ Options can be number or hash. We support `:requireBlueprintName` and `:exportSourcemap` option.
30
+
31
+ ```ruby
32
+ require 'redsnow'
33
+
34
+ result = RedSnow::parse('# My API', { :exportSourcemap => true })
35
+ puts result.ast.name
36
+ puts result.sourcemap.name
37
+ ```
38
+
27
39
  ## Hacking Redsnow
28
40
  You are welcome to contribute. Use following steps to build & test Redsnow.
29
41
 
Binary file
@@ -2622,9 +2622,12 @@ sd_markdown_render(struct buf *ob, const uint8_t *document, size_t doc_size, str
2622
2622
  beg += 3;
2623
2623
 
2624
2624
  while (beg < doc_size) /* iterating over lines */
2625
- if (is_ref(document, beg, doc_size, &end, md->refs))
2625
+ if (is_ref(document, beg, doc_size, &end, md->refs)) {
2626
+ if (end > beg)
2627
+ expand_tabs(text, document + beg, end - beg);
2628
+
2626
2629
  beg = end;
2627
- else { /* skipping to the next line */
2630
+ } else { /* skipping to the next line */
2628
2631
  end = beg;
2629
2632
  while (end < doc_size && document[end] != '\n' && document[end] != '\r')
2630
2633
  end++;
@@ -62,6 +62,8 @@
62
62
  'sources': [
63
63
  'src/CBlueprint.cc',
64
64
  'src/CBlueprint.h',
65
+ 'src/CBlueprintSourcemap.cc',
66
+ 'src/CBlueprintSourcemap.h',
65
67
  'src/CSourceAnnotation.cc',
66
68
  'src/CSourceAnnotation.h',
67
69
  'src/HTTP.cc',
@@ -88,6 +90,7 @@
88
90
  'src/AssetParser.h',
89
91
  'src/Blueprint.h',
90
92
  'src/BlueprintParser.h',
93
+ 'src/BlueprintSourcemap.h',
91
94
  'src/BlueprintUtility.h',
92
95
  'src/CodeBlockUtility.h',
93
96
  'src/HeadersParser.h',
@@ -160,7 +163,8 @@
160
163
  'src',
161
164
  'src/snowcrash',
162
165
  'ext/markdown-parser/src',
163
- 'cmdline'
166
+ 'ext/markdown-parser/ext/sundown/src',
167
+ 'ext/cmdline'
164
168
  ],
165
169
  'sources': [
166
170
  'src/snowcrash/snowcrash.cc'
@@ -176,7 +180,8 @@
176
180
  'include_dirs': [
177
181
  'src',
178
182
  'ext/markdown-parser/src',
179
- 'cmdline',
183
+ 'ext/markdown-parser/ext/sundown/src',
184
+ 'ext/cmdline',
180
185
  'test',
181
186
  'test/performance',
182
187
  ],
@@ -23,9 +23,7 @@ namespace snowcrash {
23
23
  /** Named action matching regex */
24
24
  const char* const NamedActionHeaderRegex = "^[[:blank:]]*" SYMBOL_IDENTIFIER "\\[" HTTP_REQUEST_METHOD "]$";
25
25
 
26
- /** Internal type alias for Collection of Action */
27
- typedef Collection<Action>::type Actions;
28
-
26
+ /** Internal type alias for Collection iterator of Action */
29
27
  typedef Collection<Action>::const_iterator ActionIterator;
30
28
 
31
29
  /** Action Definition Type */
@@ -46,17 +44,30 @@ namespace snowcrash {
46
44
  const MarkdownNodes& siblings,
47
45
  SectionParserData& pd,
48
46
  SectionLayout& layout,
49
- Report& report,
50
- Action& out) {
47
+ ParseResult<Action>& out) {
51
48
 
52
- actionHTTPMethodAndName(node, out.method, out.name);
53
- TrimString(out.name);
49
+ actionHTTPMethodAndName(node, out.node.method, out.node.name);
50
+ TrimString(out.node.name);
54
51
 
55
52
  mdp::ByteBuffer remainingContent;
56
53
  GetFirstLine(node->text, remainingContent);
57
54
 
55
+ if (pd.exportSourceMap()) {
56
+ if (!out.node.method.empty()) {
57
+ out.sourceMap.method.sourceMap = node->sourceMap;
58
+ }
59
+
60
+ if (!out.node.name.empty()) {
61
+ out.sourceMap.name.sourceMap = node->sourceMap;
62
+ }
63
+ }
64
+
58
65
  if (!remainingContent.empty()) {
59
- out.description += remainingContent;
66
+ out.node.description += remainingContent;
67
+
68
+ if (pd.exportSourceMap()) {
69
+ out.sourceMap.description.sourceMap.append(node->sourceMap);
70
+ }
60
71
  }
61
72
 
62
73
  return ++MarkdownNodeIterator(node);
@@ -65,50 +76,82 @@ namespace snowcrash {
65
76
  static MarkdownNodeIterator processNestedSection(const MarkdownNodeIterator& node,
66
77
  const MarkdownNodes& siblings,
67
78
  SectionParserData& pd,
68
- Report& report,
69
- Action& out) {
79
+ ParseResult<Action>& out) {
70
80
 
71
81
  SectionType sectionType = pd.sectionContext();
72
82
  MarkdownNodeIterator cur = node;
73
- Payload payload;
74
83
  std::stringstream ss;
75
84
 
76
85
  mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
77
86
 
78
87
  switch (sectionType) {
79
88
  case ParametersSectionType:
80
- return ParametersParser::parse(node, siblings, pd, report, out.parameters);
89
+ {
90
+ ParseResult<Parameters> parameters(out.report, out.node.parameters, out.sourceMap.parameters);
91
+ return ParametersParser::parse(node, siblings, pd, parameters);
92
+ }
81
93
 
82
94
  case RequestSectionType:
83
95
  case RequestBodySectionType:
84
- cur = PayloadParser::parse(node, siblings, pd, report, payload);
96
+ {
97
+ ParseResult<Payload> payload(out.report);
98
+ cur = PayloadParser::parse(node, siblings, pd, payload);
85
99
 
86
- if (out.examples.empty() || !out.examples.back().responses.empty()) {
100
+ if (out.node.examples.empty() || !out.node.examples.back().responses.empty()) {
87
101
  TransactionExample transaction;
88
- out.examples.push_back(transaction);
102
+ SourceMap<TransactionExample> transactionSM;
103
+
104
+ out.node.examples.push_back(transaction);
105
+
106
+ if (pd.exportSourceMap()) {
107
+ out.sourceMap.examples.collection.push_back(transactionSM);
108
+ }
89
109
  }
90
110
 
91
- checkPayload(sectionType, sourceMap, payload, out, report);
111
+ checkPayload(sectionType, sourceMap, payload.node, out);
112
+
113
+ out.node.examples.back().requests.push_back(payload.node);
114
+
115
+ if (pd.exportSourceMap()) {
116
+ out.sourceMap.examples.collection.back().requests.collection.push_back(payload.sourceMap);
117
+ }
92
118
 
93
- out.examples.back().requests.push_back(payload);
94
119
  break;
120
+ }
95
121
 
96
122
  case ResponseSectionType:
97
123
  case ResponseBodySectionType:
98
- cur = PayloadParser::parse(node, siblings, pd, report, payload);
124
+ {
125
+ ParseResult<Payload> payload(out.report);
126
+ cur = PayloadParser::parse(node, siblings, pd, payload);
99
127
 
100
- if (out.examples.empty()) {
128
+ if (out.node.examples.empty()) {
101
129
  TransactionExample transaction;
102
- out.examples.push_back(transaction);
130
+ SourceMap<TransactionExample> transactionSM;
131
+
132
+ out.node.examples.push_back(transaction);
133
+
134
+ if (pd.exportSourceMap()) {
135
+ out.sourceMap.examples.collection.push_back(transactionSM);
136
+ }
103
137
  }
104
138
 
105
- checkPayload(sectionType, sourceMap, payload, out, report);
139
+ checkPayload(sectionType, sourceMap, payload.node, out);
140
+
141
+ out.node.examples.back().responses.push_back(payload.node);
142
+
143
+ if (pd.exportSourceMap()) {
144
+ out.sourceMap.examples.collection.back().responses.collection.push_back(payload.sourceMap);
145
+ }
106
146
 
107
- out.examples.back().responses.push_back(payload);
108
147
  break;
148
+ }
109
149
 
110
150
  case HeadersSectionType:
111
- return SectionProcessor<Action>::handleDeprecatedHeaders(node, siblings, pd, report, out.headers);
151
+ {
152
+ ParseResult<Headers> headers(out.report, out.node.headers, out.sourceMap.headers);
153
+ return SectionProcessor<Action>::handleDeprecatedHeaders(node, siblings, pd, headers);
154
+ }
112
155
 
113
156
  default:
114
157
  break;
@@ -120,7 +163,7 @@ namespace snowcrash {
120
163
  static bool isUnexpectedNode(const MarkdownNodeIterator& node,
121
164
  SectionType sectionType) {
122
165
 
123
- if ( SectionProcessor<Asset>::sectionType(node) != UndefinedSectionType) {
166
+ if (SectionProcessor<Asset>::sectionType(node) != UndefinedSectionType) {
124
167
  return true;
125
168
  }
126
169
 
@@ -131,18 +174,21 @@ namespace snowcrash {
131
174
  const MarkdownNodes& siblings,
132
175
  SectionParserData& pd,
133
176
  SectionType& sectionType,
134
- Report& report,
135
- Action& out) {
177
+ ParseResult<Action>& out) {
136
178
 
137
179
  if ((node->type == mdp::ParagraphMarkdownNodeType ||
138
180
  node->type == mdp::CodeMarkdownNodeType) &&
139
181
  (sectionType == ResponseBodySectionType ||
140
182
  sectionType == ResponseSectionType) &&
141
- !out.examples.empty() &&
142
- !out.examples.back().responses.empty()) {
183
+ !out.node.examples.empty() &&
184
+ !out.node.examples.back().responses.empty()) {
185
+
186
+ mdp::ByteBuffer content = CodeBlockUtility::addDanglingAsset(node, pd, sectionType, out.report, out.node.examples.back().responses.back().body);
187
+
188
+ if (pd.exportSourceMap() && !content.empty()) {
189
+ out.sourceMap.examples.collection.back().responses.collection.back().body.sourceMap.append(node->sourceMap);
190
+ }
143
191
 
144
- CodeBlockUtility::addDanglingAsset(node, pd, sectionType, report, out.examples.back().responses.back().body);
145
-
146
192
  return ++MarkdownNodeIterator(node);
147
193
  }
148
194
 
@@ -150,11 +196,15 @@ namespace snowcrash {
150
196
  node->type == mdp::CodeMarkdownNodeType) &&
151
197
  (sectionType == RequestBodySectionType ||
152
198
  sectionType == RequestSectionType) &&
153
- !out.examples.empty() &&
154
- !out.examples.back().requests.empty()) {
155
-
156
- CodeBlockUtility::addDanglingAsset(node, pd, sectionType, report, out.examples.back().requests.back().body);
199
+ !out.node.examples.empty() &&
200
+ !out.node.examples.back().requests.empty()) {
157
201
 
202
+ mdp::ByteBuffer content = CodeBlockUtility::addDanglingAsset(node, pd, sectionType, out.report, out.node.examples.back().requests.back().body);
203
+
204
+ if (pd.exportSourceMap() && !content.empty()) {
205
+ out.sourceMap.examples.collection.back().requests.collection.back().body.sourceMap.append(node->sourceMap);
206
+ }
207
+
158
208
  return ++MarkdownNodeIterator(node);
159
209
  }
160
210
 
@@ -169,14 +219,14 @@ namespace snowcrash {
169
219
  ss << "Ignoring " << SectionName(assetType) << " list item, ";
170
220
  ss << SectionName(assetType) << " list item is expected to be indented by 4 spaces or 1 tab";
171
221
 
172
- report.warnings.push_back(Warning(ss.str(),
173
- IgnoringWarning,
174
- sourceMap));
222
+ out.report.warnings.push_back(Warning(ss.str(),
223
+ IgnoringWarning,
224
+ sourceMap));
175
225
 
176
226
  return ++MarkdownNodeIterator(node);
177
227
  }
178
228
 
179
- return SectionProcessorBase<Action>::processUnexpectedNode(node, siblings, pd, sectionType, report, out);
229
+ return SectionProcessorBase<Action>::processUnexpectedNode(node, siblings, pd, sectionType, out);
180
230
  }
181
231
 
182
232
  static SectionType sectionType(const MarkdownNodeIterator& node) {
@@ -242,40 +292,43 @@ namespace snowcrash {
242
292
 
243
293
  static void finalize(const MarkdownNodeIterator& node,
244
294
  SectionParserData& pd,
245
- Report& report,
246
- Action& out) {
295
+ ParseResult<Action>& out) {
296
+
297
+ if (!out.node.headers.empty()) {
247
298
 
248
- if (!out.headers.empty()) {
299
+ SectionProcessor<Headers>::injectDeprecatedHeaders(pd, out.node.headers, out.sourceMap.headers, out.node.examples, out.sourceMap.examples);
300
+ out.node.headers.clear();
249
301
 
250
- SectionProcessor<Headers>::injectDeprecatedHeaders(out.headers, out.examples);
251
- out.headers.clear();
302
+ if (pd.exportSourceMap()) {
303
+ out.sourceMap.headers.collection.clear();
304
+ }
252
305
  }
253
306
 
254
- if (out.examples.empty()) {
307
+ if (out.node.examples.empty()) {
255
308
 
256
309
  // WARN: No response for action
257
310
  mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
258
- report.warnings.push_back(Warning("action is missing a response",
259
- EmptyDefinitionWarning,
260
- sourceMap));
261
- } else if (!out.examples.empty() &&
262
- !out.examples.back().requests.empty() &&
263
- out.examples.back().responses.empty()) {
311
+ out.report.warnings.push_back(Warning("action is missing a response",
312
+ EmptyDefinitionWarning,
313
+ sourceMap));
314
+ } else if (!out.node.examples.empty() &&
315
+ !out.node.examples.back().requests.empty() &&
316
+ out.node.examples.back().responses.empty()) {
264
317
 
265
318
  // WARN: No response for request
266
319
  std::stringstream ss;
267
320
  ss << "action is missing a response for ";
268
321
 
269
- if (out.examples.back().requests.back().name.empty()) {
322
+ if (out.node.examples.back().requests.back().name.empty()) {
270
323
  ss << "a request";
271
324
  } else {
272
- ss << "the '" << out.examples.back().requests.back().name << "' request";
325
+ ss << "the '" << out.node.examples.back().requests.back().name << "' request";
273
326
  }
274
327
 
275
328
  mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
276
- report.warnings.push_back(Warning(ss.str(),
277
- EmptyDefinitionWarning,
278
- sourceMap));
329
+ out.report.warnings.push_back(Warning(ss.str(),
330
+ EmptyDefinitionWarning,
331
+ sourceMap));
279
332
  }
280
333
  }
281
334
 
@@ -290,19 +343,18 @@ namespace snowcrash {
290
343
  static void checkPayload(SectionType sectionType,
291
344
  const mdp::CharactersRangeSet sourceMap,
292
345
  const Payload& payload,
293
- const Action& action,
294
- Report& report) {
346
+ ParseResult<Action>& out) {
295
347
 
296
- if (isPayloadDuplicate(sectionType, payload, action.examples.back())) {
348
+ if (isPayloadDuplicate(sectionType, payload, out.node.examples.back())) {
297
349
 
298
350
  // WARN: Duplicate payload
299
351
  std::stringstream ss;
300
352
  ss << SectionName(sectionType) << " payload `" << payload.name << "`";
301
- ss << " already defined for `" << action.method << "` method";
353
+ ss << " already defined for `" << out.node.method << "` method";
302
354
 
303
- report.warnings.push_back(Warning(ss.str(),
304
- DuplicateWarning,
305
- sourceMap));
355
+ out.report.warnings.push_back(Warning(ss.str(),
356
+ DuplicateWarning,
357
+ sourceMap));
306
358
  }
307
359
 
308
360
  if (sectionType == ResponseSectionType || sectionType == ResponseBodySectionType) {
@@ -313,27 +365,27 @@ namespace snowcrash {
313
365
  std::stringstream(payload.name) >> code;
314
366
  }
315
367
 
316
- HTTPMethodTraits methodTraits = GetMethodTrait(action.method);
368
+ HTTPMethodTraits methodTraits = GetMethodTrait(out.node.method);
317
369
 
318
370
  if (!methodTraits.allowBody && !payload.body.empty()) {
319
371
 
320
372
  // WARN: Edge case for 2xx CONNECT
321
- if (action.method == HTTPMethodName::Connect && code/100 == 2) {
373
+ if (out.node.method == HTTPMethodName::Connect && code/100 == 2) {
322
374
 
323
375
  std::stringstream ss;
324
- ss << "the response for " << code << " " << action.method << " request MUST NOT include a " << SectionName(BodySectionType);
376
+ ss << "the response for " << code << " " << out.node.method << " request MUST NOT include a " << SectionName(BodySectionType);
325
377
 
326
- report.warnings.push_back(Warning(ss.str(),
327
- EmptyDefinitionWarning,
328
- sourceMap));
329
- } else if (action.method != HTTPMethodName::Connect && !methodTraits.allowBody) {
378
+ out.report.warnings.push_back(Warning(ss.str(),
379
+ EmptyDefinitionWarning,
380
+ sourceMap));
381
+ } else if (out.node.method != HTTPMethodName::Connect && !methodTraits.allowBody) {
330
382
 
331
383
  std::stringstream ss;
332
- ss << "the response for " << action.method << " request MUST NOT include a " << SectionName(BodySectionType);
384
+ ss << "the response for " << out.node.method << " request MUST NOT include a " << SectionName(BodySectionType);
333
385
 
334
- report.warnings.push_back(Warning(ss.str(),
335
- EmptyDefinitionWarning,
336
- sourceMap));
386
+ out.report.warnings.push_back(Warning(ss.str(),
387
+ EmptyDefinitionWarning,
388
+ sourceMap));
337
389
  }
338
390
 
339
391
  return;
@@ -351,11 +403,11 @@ namespace snowcrash {
351
403
 
352
404
  if (sectionType == RequestSectionType) {
353
405
 
354
- Collection<Request>::const_iterator duplicate = FindRequest(example, payload);
406
+ RequestIterator duplicate = SectionProcessor<Payload>::findRequest(example, payload);
355
407
  return duplicate != example.requests.end();
356
408
  } else if (sectionType == ResponseSectionType) {
357
409
 
358
- Collection<Response>::const_iterator duplicate = FindResponse(example, payload);
410
+ ResponseIterator duplicate = SectionProcessor<Payload>::findResponse(example, payload);
359
411
  return duplicate != example.responses.end();
360
412
  }
361
413
 
@@ -366,19 +418,18 @@ namespace snowcrash {
366
418
  static MarkdownNodeIterator handleDeprecatedHeaders(const MarkdownNodeIterator& node,
367
419
  const MarkdownNodes& siblings,
368
420
  SectionParserData& pd,
369
- Report& report,
370
- Headers& headers) {
421
+ ParseResult<Headers>& out) {
371
422
 
372
- MarkdownNodeIterator cur = HeadersParser::parse(node, siblings, pd, report, headers);
423
+ MarkdownNodeIterator cur = HeadersParser::parse(node, siblings, pd, out);
373
424
 
374
425
  // WARN: Deprecated header sections
375
426
  std::stringstream ss;
376
427
  ss << "the 'headers' section at this level is deprecated and will be removed in a future, use respective payload header section(s) instead";
377
428
 
378
429
  mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
379
- report.warnings.push_back(Warning(ss.str(),
380
- DeprecatedWarning,
381
- sourceMap));
430
+ out.report.warnings.push_back(Warning(ss.str(),
431
+ DeprecatedWarning,
432
+ sourceMap));
382
433
 
383
434
  return cur;
384
435
  }
@@ -430,6 +481,15 @@ namespace snowcrash {
430
481
 
431
482
  return;
432
483
  }
484
+
485
+ /** Finds an action inside an actions collection */
486
+ static ActionIterator findAction(const Actions& actions,
487
+ const Action& action) {
488
+
489
+ return std::find_if(actions.begin(),
490
+ actions.end(),
491
+ std::bind2nd(MatchAction<Action>(), action));
492
+ }
433
493
  };
434
494
 
435
495
  /** Action Section Parser */