Skip to content

Commit

Permalink
BRAYNS-631 Refactor JSON. (#1256)
Browse files Browse the repository at this point in the history
  • Loading branch information
Adrien4193 committed May 6, 2024
1 parent 95fe932 commit 28b76e8
Show file tree
Hide file tree
Showing 22 changed files with 2,809 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/brayns/core/jsonv2/Json.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* Copyright (c) 2015-2024 EPFL/Blue Brain Project
* All rights reserved. Do not distribute without permission.
*
* Responsible Author: [email protected]
*
* This file is part of Brayns <https://github.com/BlueBrain/Brayns>
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3.0 as published
* by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#pragma once

#include "JsonReflector.h"
#include "JsonSchema.h"
#include "JsonValidator.h"
#include "JsonValue.h"

#include "types/Arrays.h"
#include "types/Enums.h"
#include "types/Maps.h"
#include "types/Math.h"
#include "types/Objects.h"
#include "types/Primitives.h"
#include "types/Schema.h"
#include "types/Variants.h"
84 changes: 84 additions & 0 deletions src/brayns/core/jsonv2/JsonReflector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/* Copyright (c) 2015-2024 EPFL/Blue Brain Project
* All rights reserved. Do not distribute without permission.
*
* Responsible Author: [email protected]
*
* This file is part of Brayns <https://github.com/BlueBrain/Brayns>
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3.0 as published
* by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#pragma once

#include "JsonSchema.h"
#include "JsonValue.h"

namespace brayns::experimental
{
template<typename T>
struct JsonReflector
{
template<typename U>
static constexpr auto alwaysFalse = false;

static_assert(alwaysFalse<T>, "Please specialize JsonReflector<T>");

static JsonSchema getSchema()
{
return {};
}

static JsonValue serialize(const T &value)
{
return {};
}

static T deserialize(const JsonValue &json)
{
return {};
}
};

template<typename T>
JsonSchema getJsonSchema()
{
return JsonReflector<T>::getSchema();
}

template<typename T>
JsonValue serializeToJson(const T &value)
{
return JsonReflector<T>::serialize(value);
}

template<typename T>
T deserializeAs(const JsonValue &json)
{
return JsonReflector<T>::deserialize(json);
}

template<typename T>
std::string stringifyToJson(const T &value)
{
auto json = serializeToJson(value);
return stringify(json);
}

template<typename T>
T parseJson(const std::string &data)
{
auto json = parseJson(data);
return deserializeAs<T>(json);
}
}
82 changes: 82 additions & 0 deletions src/brayns/core/jsonv2/JsonSchema.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/* Copyright (c) 2015-2024 EPFL/Blue Brain Project
* All rights reserved. Do not distribute without permission.
*
* Responsible Author: [email protected]
*
* This file is part of Brayns <https://github.com/BlueBrain/Brayns>
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3.0 as published
* by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "JsonSchema.h"

#include <stdexcept>

namespace brayns::experimental
{
EnumInfo<JsonType> EnumReflector<JsonType>::reflect()
{
auto builder = EnumInfoBuilder<JsonType>();
builder.field("undefined", JsonType::Undefined);
builder.field("null", JsonType::Null);
builder.field("boolean", JsonType::Boolean);
builder.field("integer", JsonType::Integer);
builder.field("number", JsonType::Number);
builder.field("string", JsonType::String);
builder.field("array", JsonType::Array);
builder.field("object", JsonType::Object);
return builder.build();
}

JsonType getJsonType(const JsonValue &json)
{
if (json.isEmpty())
{
return JsonType::Null;
}
if (json.isBoolean())
{
return JsonType::Boolean;
}
if (json.isInteger())
{
return JsonType::Integer;
}
if (json.isNumeric())
{
return JsonType::Number;
}
if (json.isString())
{
return JsonType::String;
}
if (isArray(json))
{
return JsonType::Array;
}
if (isObject(json))
{
return JsonType::Object;
}
throw JsonException("Value is not JSON");
}

void RequiredJsonType::throwIfNotCompatible(JsonType type)
{
if (!isCompatible(type))
{
throw JsonException("Incompatible JSON types");
}
}
}
166 changes: 166 additions & 0 deletions src/brayns/core/jsonv2/JsonSchema.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/* Copyright (c) 2015-2024 EPFL/Blue Brain Project
* All rights reserved. Do not distribute without permission.
*
* Responsible Author: [email protected]
*
* This file is part of Brayns <https://github.com/BlueBrain/Brayns>
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3.0 as published
* by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#pragma once

#include <concepts>
#include <map>
#include <optional>
#include <string>
#include <type_traits>
#include <vector>

#include <brayns/core/utils/EnumReflector.h>

#include "JsonValue.h"

namespace brayns::experimental
{
enum class JsonType
{
Unknown,
Undefined,
Null,
Boolean,
Integer,
Number,
String,
Array,
Object,
};

template<>
struct EnumReflector<JsonType>
{
static EnumInfo<JsonType> reflect();
};

constexpr bool isNumeric(JsonType type)
{
return type == JsonType::Integer || type == JsonType::Number;
}

constexpr bool isPrimitive(JsonType type)
{
return type >= JsonType::Undefined && type <= JsonType::String;
}

template<typename T>
struct JsonTypeReflector
{
static inline constexpr auto type = JsonType::Unknown;
};

template<>
struct JsonTypeReflector<JsonValue>
{
static inline constexpr auto type = JsonType::Undefined;
};

template<>
struct JsonTypeReflector<NullJson>
{
static inline constexpr auto type = JsonType::Null;
};

template<>
struct JsonTypeReflector<bool>
{
static inline constexpr auto type = JsonType::Boolean;
};

template<std::integral T>
struct JsonTypeReflector<T>
{
static inline constexpr auto type = JsonType::Integer;
};

template<std::floating_point T>
struct JsonTypeReflector<T>
{
static inline constexpr auto type = JsonType::Number;
};

template<>
struct JsonTypeReflector<std::string>
{
static inline constexpr auto type = JsonType::String;
};

template<typename T>
constexpr JsonType jsonTypeOf = JsonTypeReflector<T>::type;

JsonType getJsonType(const JsonValue &json);

struct RequiredJsonType
{
JsonType value;

void throwIfNotCompatible(JsonType type);

constexpr bool isCompatible(JsonType type)
{
if (value == JsonType::Unknown || type == JsonType::Unknown)
{
return false;
}
if (type == value)
{
return true;
}
if (value == JsonType::Undefined)
{
return true;
}
if (value == JsonType::Number && type == JsonType::Integer)
{
return true;
}
return false;
}
};

template<typename T>
void throwIfNotCompatible(const JsonValue &json)
{
auto type = getJsonType(json);
auto required = RequiredJsonType{jsonTypeOf<T>};
required.throwIfNotCompatible(type);
}

struct JsonSchema
{
std::string description = {};
bool required = true;
JsonValue defaultValue = {};
std::vector<JsonSchema> oneOf = {};
JsonType type = JsonType::Undefined;
std::string constant = {};
std::optional<double> minimum = {};
std::optional<double> maximum = {};
std::vector<JsonSchema> items = {};
std::optional<std::size_t> minItems = {};
std::optional<std::size_t> maxItems = {};
std::map<std::string, JsonSchema> properties = {};

auto operator<=>(const JsonSchema &) const = default;
};
}
Loading

0 comments on commit 28b76e8

Please sign in to comment.