Skip to content

Commit c40c334

Browse files
CharReader: Add StructuredError
1 parent 94cda30 commit c40c334

File tree

3 files changed

+59
-9
lines changed

3 files changed

+59
-9
lines changed

Diff for: include/json/reader.h

+13
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,13 @@ class JSONCPP_DEPRECATED(
244244
*/
245245
class JSON_API CharReader {
246246
public:
247+
class JSON_API StructuredError {
248+
public:
249+
ptrdiff_t offset_start;
250+
ptrdiff_t offset_limit;
251+
String message;
252+
};
253+
247254
virtual ~CharReader() = default;
248255
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
249256
* document. The document must be a UTF-8 encoded string containing the
@@ -264,6 +271,12 @@ class JSON_API CharReader {
264271
virtual bool parse(char const* beginDoc, char const* endDoc, Value* root,
265272
String* errs) = 0;
266273

274+
/** \brief Get a list of structured error messages from parsing the document.
275+
*
276+
* \return list of error messages.
277+
*/
278+
virtual std::vector<StructuredError> getStructuredErrors() const = 0;
279+
267280
class JSON_API Factory {
268281
public:
269282
virtual ~Factory() = default;

Diff for: src/lib_json/json_reader.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -884,17 +884,12 @@ class OurReader {
884884
public:
885885
using Char = char;
886886
using Location = const Char*;
887-
struct StructuredError {
888-
ptrdiff_t offset_start;
889-
ptrdiff_t offset_limit;
890-
String message;
891-
};
892887

893888
explicit OurReader(OurFeatures const& features);
894889
bool parse(const char* beginDoc, const char* endDoc, Value& root,
895890
bool collectComments = true);
896891
String getFormattedErrorMessages() const;
897-
std::vector<StructuredError> getStructuredErrors() const;
892+
std::vector<CharReader::StructuredError> getStructuredErrors() const;
898893

899894
private:
900895
OurReader(OurReader const&); // no impl
@@ -1849,10 +1844,11 @@ String OurReader::getFormattedErrorMessages() const {
18491844
return formattedMessage;
18501845
}
18511846

1852-
std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
1853-
std::vector<OurReader::StructuredError> allErrors;
1847+
std::vector<CharReader::StructuredError>
1848+
OurReader::getStructuredErrors() const {
1849+
std::vector<CharReader::StructuredError> allErrors;
18541850
for (const auto& error : errors_) {
1855-
OurReader::StructuredError structured;
1851+
CharReader::StructuredError structured;
18561852
structured.offset_start = error.token_.start_ - begin_;
18571853
structured.offset_limit = error.token_.end_ - begin_;
18581854
structured.message = error.message_;
@@ -1876,6 +1872,10 @@ class OurCharReader : public CharReader {
18761872
}
18771873
return ok;
18781874
}
1875+
1876+
std::vector<StructuredError> getStructuredErrors() const override {
1877+
return reader_.getStructuredErrors();
1878+
}
18791879
};
18801880

18811881
CharReaderBuilder::CharReaderBuilder() { setDefaults(&settings_); }

Diff for: src/test_lib_json/main.cpp

+37
Original file line numberDiff line numberDiff line change
@@ -3903,6 +3903,43 @@ JSONTEST_FIXTURE_LOCAL(FuzzTest, fuzzDoesntCrash) {
39033903
example.size()));
39043904
}
39053905

3906+
struct ParseWithStructuredErrorsTest : JsonTest::TestCase {
3907+
void
3908+
testErrors(const std::string& doc, bool success,
3909+
const std::vector<Json::CharReader::StructuredError>& errors) {
3910+
Json::CharReaderBuilder b;
3911+
CharReaderPtr reader(b.newCharReader());
3912+
Json::Value root;
3913+
JSONTEST_ASSERT_EQUAL(
3914+
success,
3915+
reader->parse(doc.data(), doc.data() + doc.length(), &root, nullptr));
3916+
auto actualErrors = reader->getStructuredErrors();
3917+
JSONTEST_ASSERT_EQUAL(errors.size(), actualErrors.size());
3918+
for (std::size_t i = 0; i < errors.size() && i < actualErrors.size(); i++) {
3919+
JSONTEST_ASSERT_EQUAL(errors[i].offset_start,
3920+
actualErrors[i].offset_start);
3921+
JSONTEST_ASSERT_EQUAL(errors[i].offset_limit,
3922+
actualErrors[i].offset_limit);
3923+
JSONTEST_ASSERT_STRING_EQUAL(errors[i].message, actualErrors[i].message);
3924+
}
3925+
}
3926+
};
3927+
3928+
JSONTEST_FIXTURE_LOCAL(ParseWithStructuredErrorsTest, success) {
3929+
testErrors("{}", true, {});
3930+
}
3931+
3932+
JSONTEST_FIXTURE_LOCAL(ParseWithStructuredErrorsTest, singleError) {
3933+
testErrors("{ 1 : 2 }", false,
3934+
{
3935+
{
3936+
/*offset_start=*/2,
3937+
/*offset_limit=*/3,
3938+
/*message=*/"Missing '}' or object member name",
3939+
},
3940+
});
3941+
}
3942+
39063943
int main(int argc, const char* argv[]) {
39073944
JsonTest::Runner runner;
39083945

0 commit comments

Comments
 (0)