Skip to content

Commit 28b76e8

Browse files
authored
BRAYNS-631 Refactor JSON. (#1256)
1 parent 95fe932 commit 28b76e8

22 files changed

+2809
-0
lines changed

src/brayns/core/jsonv2/Json.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/* Copyright (c) 2015-2024 EPFL/Blue Brain Project
2+
* All rights reserved. Do not distribute without permission.
3+
*
4+
* Responsible Author: [email protected]
5+
*
6+
* This file is part of Brayns <https://github.com/BlueBrain/Brayns>
7+
*
8+
* This library is free software; you can redistribute it and/or modify it under
9+
* the terms of the GNU Lesser General Public License version 3.0 as published
10+
* by the Free Software Foundation.
11+
*
12+
* This library is distributed in the hope that it will be useful, but WITHOUT
13+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14+
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15+
* details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public License
18+
* along with this library; if not, write to the Free Software Foundation, Inc.,
19+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*/
21+
22+
#pragma once
23+
24+
#include "JsonReflector.h"
25+
#include "JsonSchema.h"
26+
#include "JsonValidator.h"
27+
#include "JsonValue.h"
28+
29+
#include "types/Arrays.h"
30+
#include "types/Enums.h"
31+
#include "types/Maps.h"
32+
#include "types/Math.h"
33+
#include "types/Objects.h"
34+
#include "types/Primitives.h"
35+
#include "types/Schema.h"
36+
#include "types/Variants.h"
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/* Copyright (c) 2015-2024 EPFL/Blue Brain Project
2+
* All rights reserved. Do not distribute without permission.
3+
*
4+
* Responsible Author: [email protected]
5+
*
6+
* This file is part of Brayns <https://github.com/BlueBrain/Brayns>
7+
*
8+
* This library is free software; you can redistribute it and/or modify it under
9+
* the terms of the GNU Lesser General Public License version 3.0 as published
10+
* by the Free Software Foundation.
11+
*
12+
* This library is distributed in the hope that it will be useful, but WITHOUT
13+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14+
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15+
* details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public License
18+
* along with this library; if not, write to the Free Software Foundation, Inc.,
19+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*/
21+
22+
#pragma once
23+
24+
#include "JsonSchema.h"
25+
#include "JsonValue.h"
26+
27+
namespace brayns::experimental
28+
{
29+
template<typename T>
30+
struct JsonReflector
31+
{
32+
template<typename U>
33+
static constexpr auto alwaysFalse = false;
34+
35+
static_assert(alwaysFalse<T>, "Please specialize JsonReflector<T>");
36+
37+
static JsonSchema getSchema()
38+
{
39+
return {};
40+
}
41+
42+
static JsonValue serialize(const T &value)
43+
{
44+
return {};
45+
}
46+
47+
static T deserialize(const JsonValue &json)
48+
{
49+
return {};
50+
}
51+
};
52+
53+
template<typename T>
54+
JsonSchema getJsonSchema()
55+
{
56+
return JsonReflector<T>::getSchema();
57+
}
58+
59+
template<typename T>
60+
JsonValue serializeToJson(const T &value)
61+
{
62+
return JsonReflector<T>::serialize(value);
63+
}
64+
65+
template<typename T>
66+
T deserializeAs(const JsonValue &json)
67+
{
68+
return JsonReflector<T>::deserialize(json);
69+
}
70+
71+
template<typename T>
72+
std::string stringifyToJson(const T &value)
73+
{
74+
auto json = serializeToJson(value);
75+
return stringify(json);
76+
}
77+
78+
template<typename T>
79+
T parseJson(const std::string &data)
80+
{
81+
auto json = parseJson(data);
82+
return deserializeAs<T>(json);
83+
}
84+
}

src/brayns/core/jsonv2/JsonSchema.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/* Copyright (c) 2015-2024 EPFL/Blue Brain Project
2+
* All rights reserved. Do not distribute without permission.
3+
*
4+
* Responsible Author: [email protected]
5+
*
6+
* This file is part of Brayns <https://github.com/BlueBrain/Brayns>
7+
*
8+
* This library is free software; you can redistribute it and/or modify it under
9+
* the terms of the GNU Lesser General Public License version 3.0 as published
10+
* by the Free Software Foundation.
11+
*
12+
* This library is distributed in the hope that it will be useful, but WITHOUT
13+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14+
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15+
* details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public License
18+
* along with this library; if not, write to the Free Software Foundation, Inc.,
19+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*/
21+
22+
#include "JsonSchema.h"
23+
24+
#include <stdexcept>
25+
26+
namespace brayns::experimental
27+
{
28+
EnumInfo<JsonType> EnumReflector<JsonType>::reflect()
29+
{
30+
auto builder = EnumInfoBuilder<JsonType>();
31+
builder.field("undefined", JsonType::Undefined);
32+
builder.field("null", JsonType::Null);
33+
builder.field("boolean", JsonType::Boolean);
34+
builder.field("integer", JsonType::Integer);
35+
builder.field("number", JsonType::Number);
36+
builder.field("string", JsonType::String);
37+
builder.field("array", JsonType::Array);
38+
builder.field("object", JsonType::Object);
39+
return builder.build();
40+
}
41+
42+
JsonType getJsonType(const JsonValue &json)
43+
{
44+
if (json.isEmpty())
45+
{
46+
return JsonType::Null;
47+
}
48+
if (json.isBoolean())
49+
{
50+
return JsonType::Boolean;
51+
}
52+
if (json.isInteger())
53+
{
54+
return JsonType::Integer;
55+
}
56+
if (json.isNumeric())
57+
{
58+
return JsonType::Number;
59+
}
60+
if (json.isString())
61+
{
62+
return JsonType::String;
63+
}
64+
if (isArray(json))
65+
{
66+
return JsonType::Array;
67+
}
68+
if (isObject(json))
69+
{
70+
return JsonType::Object;
71+
}
72+
throw JsonException("Value is not JSON");
73+
}
74+
75+
void RequiredJsonType::throwIfNotCompatible(JsonType type)
76+
{
77+
if (!isCompatible(type))
78+
{
79+
throw JsonException("Incompatible JSON types");
80+
}
81+
}
82+
}

src/brayns/core/jsonv2/JsonSchema.h

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/* Copyright (c) 2015-2024 EPFL/Blue Brain Project
2+
* All rights reserved. Do not distribute without permission.
3+
*
4+
* Responsible Author: [email protected]
5+
*
6+
* This file is part of Brayns <https://github.com/BlueBrain/Brayns>
7+
*
8+
* This library is free software; you can redistribute it and/or modify it under
9+
* the terms of the GNU Lesser General Public License version 3.0 as published
10+
* by the Free Software Foundation.
11+
*
12+
* This library is distributed in the hope that it will be useful, but WITHOUT
13+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14+
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15+
* details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public License
18+
* along with this library; if not, write to the Free Software Foundation, Inc.,
19+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*/
21+
22+
#pragma once
23+
24+
#include <concepts>
25+
#include <map>
26+
#include <optional>
27+
#include <string>
28+
#include <type_traits>
29+
#include <vector>
30+
31+
#include <brayns/core/utils/EnumReflector.h>
32+
33+
#include "JsonValue.h"
34+
35+
namespace brayns::experimental
36+
{
37+
enum class JsonType
38+
{
39+
Unknown,
40+
Undefined,
41+
Null,
42+
Boolean,
43+
Integer,
44+
Number,
45+
String,
46+
Array,
47+
Object,
48+
};
49+
50+
template<>
51+
struct EnumReflector<JsonType>
52+
{
53+
static EnumInfo<JsonType> reflect();
54+
};
55+
56+
constexpr bool isNumeric(JsonType type)
57+
{
58+
return type == JsonType::Integer || type == JsonType::Number;
59+
}
60+
61+
constexpr bool isPrimitive(JsonType type)
62+
{
63+
return type >= JsonType::Undefined && type <= JsonType::String;
64+
}
65+
66+
template<typename T>
67+
struct JsonTypeReflector
68+
{
69+
static inline constexpr auto type = JsonType::Unknown;
70+
};
71+
72+
template<>
73+
struct JsonTypeReflector<JsonValue>
74+
{
75+
static inline constexpr auto type = JsonType::Undefined;
76+
};
77+
78+
template<>
79+
struct JsonTypeReflector<NullJson>
80+
{
81+
static inline constexpr auto type = JsonType::Null;
82+
};
83+
84+
template<>
85+
struct JsonTypeReflector<bool>
86+
{
87+
static inline constexpr auto type = JsonType::Boolean;
88+
};
89+
90+
template<std::integral T>
91+
struct JsonTypeReflector<T>
92+
{
93+
static inline constexpr auto type = JsonType::Integer;
94+
};
95+
96+
template<std::floating_point T>
97+
struct JsonTypeReflector<T>
98+
{
99+
static inline constexpr auto type = JsonType::Number;
100+
};
101+
102+
template<>
103+
struct JsonTypeReflector<std::string>
104+
{
105+
static inline constexpr auto type = JsonType::String;
106+
};
107+
108+
template<typename T>
109+
constexpr JsonType jsonTypeOf = JsonTypeReflector<T>::type;
110+
111+
JsonType getJsonType(const JsonValue &json);
112+
113+
struct RequiredJsonType
114+
{
115+
JsonType value;
116+
117+
void throwIfNotCompatible(JsonType type);
118+
119+
constexpr bool isCompatible(JsonType type)
120+
{
121+
if (value == JsonType::Unknown || type == JsonType::Unknown)
122+
{
123+
return false;
124+
}
125+
if (type == value)
126+
{
127+
return true;
128+
}
129+
if (value == JsonType::Undefined)
130+
{
131+
return true;
132+
}
133+
if (value == JsonType::Number && type == JsonType::Integer)
134+
{
135+
return true;
136+
}
137+
return false;
138+
}
139+
};
140+
141+
template<typename T>
142+
void throwIfNotCompatible(const JsonValue &json)
143+
{
144+
auto type = getJsonType(json);
145+
auto required = RequiredJsonType{jsonTypeOf<T>};
146+
required.throwIfNotCompatible(type);
147+
}
148+
149+
struct JsonSchema
150+
{
151+
std::string description = {};
152+
bool required = true;
153+
JsonValue defaultValue = {};
154+
std::vector<JsonSchema> oneOf = {};
155+
JsonType type = JsonType::Undefined;
156+
std::string constant = {};
157+
std::optional<double> minimum = {};
158+
std::optional<double> maximum = {};
159+
std::vector<JsonSchema> items = {};
160+
std::optional<std::size_t> minItems = {};
161+
std::optional<std::size_t> maxItems = {};
162+
std::map<std::string, JsonSchema> properties = {};
163+
164+
auto operator<=>(const JsonSchema &) const = default;
165+
};
166+
}

0 commit comments

Comments
 (0)