Skip to content

Commit 322f8ac

Browse files
committed
feat chaotic: allow SAX parsing of recursive arrays
Tests: протестировано CI commit_hash:fa31d32d10e3a36018b924d338794174b571077a
1 parent 888559f commit 322f8ac

File tree

3 files changed

+72
-12
lines changed

3 files changed

+72
-12
lines changed

chaotic/include/userver/chaotic/sax_parser.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ class WithValidators final : private formats::json::parser::Subscriber<typename
6666

6767
void Subscribe(formats::json::parser::Subscriber<ResultType>& subscriber) { subscriber_ = &subscriber; }
6868

69-
formats::json::parser::BaseParser& GetParser() { return parser_; }
69+
formats::json::parser::BaseParser& GetParser() { return parser_.GetParser(); }
7070

7171
private:
7272
void OnSend(ResultType&& value) override {
7373
[[maybe_unused]] const auto error_reporter = [this](std::string_view error) {
74-
formats::json::parser::BaseParser& base = parser_;
74+
formats::json::parser::BaseParser& base = parser_.GetParser();
7575
chaotic::ThrowForPath<formats::json::Value>(error, base.GetCurrentPath());
7676
};
7777
(Validator::Validate(value, error_reporter), ...);
Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#include <memory>
4+
35
#include <userver/formats/json/parser/typed_parser.hpp>
46

57
USERVER_NAMESPACE_BEGIN
@@ -13,28 +15,33 @@ class JoinedParser final {
1315
public:
1416
using ResultType = typename ParserA::ResultType;
1517

16-
JoinedParser()
17-
: main_parser_(subparser_)
18-
{}
18+
JoinedParser();
19+
~JoinedParser();
1920

2021
void Reset() { main_parser_.Reset(); }
2122

2223
void Subscribe(formats::json::parser::Subscriber<typename ParserA::ResultType>& subscriber) {
2324
main_parser_.Subscribe(subscriber);
2425
}
2526

26-
auto& GetParser() { return main_parser_; }
27-
28-
operator formats::json::parser::BaseParser&()
29-
{
30-
return main_parser_;
31-
}
27+
formats::json::parser::BaseParser& GetParser() { return main_parser_; }
3228

3329
private:
34-
ParserB subparser_;
30+
// We use std::unique_ptr here to break the circular dependency for recursive types in the same way as it is
31+
// implicitly done in DOM.
32+
std::unique_ptr<ParserB> subparser_;
3533
ParserA main_parser_;
3634
};
3735

36+
template <typename ParserA, typename ParserB>
37+
JoinedParser<ParserA, ParserB>::JoinedParser()
38+
: subparser_(std::make_unique<ParserB>()),
39+
main_parser_(*subparser_)
40+
{}
41+
42+
template <typename ParserA, typename ParserB>
43+
JoinedParser<ParserA, ParserB>::~JoinedParser() = default;
44+
3845
} // namespace chaotic::sax
3946

4047
USERVER_NAMESPACE_END

chaotic/integration_tests/schemas/recursion.yaml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,56 @@ definitions:
99
type: array
1010
items:
1111
$ref: '#/definitions/RecursiveObject'
12+
13+
RecursiveEntityA:
14+
type: object
15+
additionalProperties: false
16+
properties:
17+
field1:
18+
type: array
19+
items:
20+
$ref: "#/definitions/RecursiveEntityB"
21+
field2:
22+
type: array
23+
items:
24+
$ref: "#/definitions/RecursiveEntityC"
25+
26+
RecursiveEntityB:
27+
type: object
28+
additionalProperties:
29+
type: string
30+
properties:
31+
field3:
32+
oneOf:
33+
- type: string
34+
- type: array
35+
items:
36+
type: string
37+
field4:
38+
type: array
39+
items:
40+
type: string
41+
field5:
42+
type: array
43+
items:
44+
$ref: "#/definitions/RecursiveEntityB"
45+
field6:
46+
type: string
47+
48+
RecursiveEntityC:
49+
type: object
50+
additionalProperties:
51+
type: string
52+
properties:
53+
field7:
54+
type: string
55+
field8:
56+
oneOf:
57+
- type: string
58+
- type: array
59+
items:
60+
type: string
61+
field9:
62+
type: array
63+
items:
64+
$ref: "#/definitions/RecursiveEntityC"

0 commit comments

Comments
 (0)