Skip to content

Commit

Permalink
feat(schema): generate schema json, ref #149
Browse files Browse the repository at this point in the history
  • Loading branch information
iboB committed Dec 3, 2024
1 parent 5fd3ffd commit d8af2d0
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 49 deletions.
8 changes: 4 additions & 4 deletions astl/include/astl/tuple_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ template <typename Func>
struct expand_for_each {
Func& f;
template <typename... Args>
constexpr void operator()(Args&... args) {
(f(args), ...);
constexpr void operator()(Args&&... args) {
(f(std::forward<Args>(args)), ...);
}
};
} // namespace impl

template <typename Tuple, typename Func>
constexpr void for_each(Tuple& tup, Func f) {
std::apply(impl::expand_for_each{f}, tup);
constexpr void for_each(Tuple&& tup, Func f) {
std::apply(impl::expand_for_each{f}, std::forward<Tuple>(tup));
}

} // namespace astl::tuple
4 changes: 4 additions & 0 deletions dummy-plugin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ if(AC_LOCAL_BUILD_TESTS OR AC_LOCAL_BUILD_EXAMPLES)
endif()

ac_local_add_test_subdir()

if(AC_LOCAL_BUILD_EXAMPLES)
add_subdirectory(example)
endif()
2 changes: 1 addition & 1 deletion dummy-plugin/code/ac/dummy/DummyInterface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct DummyInterface {

struct OpRun {
static constexpr auto id = "run";
static constexpr auto desc = "Run the dummy inference and produce some output";
static constexpr auto description = "Run the dummy inference and produce some output";

struct Params {
Field<std::vector<std::string>> input;
Expand Down
7 changes: 5 additions & 2 deletions dummy-plugin/code/ac/dummy/DummyLoaderSchema.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
namespace ac::local::schema {

struct DummyLoader {
static constexpr auto id = "dummy";
static inline constexpr std::string_view id = "dummy";
static inline constexpr std::string_view description = "Dummy inference for tests, examples, and experiments.";

struct Params {
Field<std::string> spliceString = std::nullopt;

Expand All @@ -19,7 +21,8 @@ struct DummyLoader {
};

struct InstanceGeneral {
static constexpr auto id = "general";
static inline constexpr std::string_view id = "general";
static inline constexpr std::string_view description = "General instance";

struct Params {
Field<int> cutoff = Default(-1);
Expand Down
11 changes: 11 additions & 0 deletions dummy-plugin/example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright (c) Alpaca Core
# SPDX-License-Identifier: MIT
#
set(tgt example-ac-local-gen-dummy-schema)
add_executable(${tgt}
e-gen-dummy-schema.cpp
)
target_link_libraries(${tgt}
ac::schema
aclp-dummy-baselib
)
12 changes: 12 additions & 0 deletions dummy-plugin/example/e-gen-dummy-schema.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) Alpaca Core
// SPDX-License-Identifier: MIT
//
#include <ac/dummy/DummyLoaderSchema.hpp>
#include <ac/schema/GenerateLoaderSchemaDict.hpp>
#include <iostream>

int main() {
auto d = ac::local::schema::generateLoaderSchema<acnl::ordered_json, ac::local::schema::DummyLoader>();
std::cout << d.dump(2) << std::endl;
return 0;
}
4 changes: 2 additions & 2 deletions local/code/ac/local/ModelLoader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class AC_LOCAL_EXPORT ModelLoader {
/// Optional human readable name of the loader vendor.
std::string vendor;

/// Model schema for the models this loader produces.
Dict modelSchema;
/// Schema for the loader.
Dict schema;

/// Additional tags that can be used to filter loaders
std::vector<std::string> tags;
Expand Down
36 changes: 36 additions & 0 deletions schema/code/ac/schema/GenerateLoaderSchemaDict.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) Alpaca Core
// SPDX-License-Identifier: MIT
//
#pragma once
#include "SchemaVisitor.hpp"
#include <astl/tuple_util.hpp>

namespace ac::local::schema {

template <typename Dict, typename Schema>
Dict generateLoaderSchema() {
Dict dict;
dict["id"] = Schema::id;
dict["description"] = Schema::description;
Struct_toSchema<typename Schema::Params>(dict["params"]);

auto& is = dict["instances"];
astl::tuple::for_each(typename Schema::Instances{}, [&]<typename Instance>(Instance) {
auto& i = is[Instance::id];
i["description"] = Instance::description;
Struct_toSchema<typename Instance::Params>(i["params"]);
auto& os = i["ops"];
astl::tuple::for_each(typename Instance::Interfaces{}, [&]<typename Interface>(Interface) {
astl::tuple::for_each(typename Interface::Ops{}, [&]<typename Op>(Op) {
auto& o = os[Op::id];
o["description"] = Op::description;
Struct_toSchema<typename Op::Params>(o["params"]);
Struct_toSchema<typename Op::Return>(o["return"]);
});
});
});

return dict;
}

}
66 changes: 26 additions & 40 deletions schema/code/ac/schema/SchemaVisitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,47 +24,33 @@ struct SchemaVisitor {
props = &out["properties"];
}

template <std::signed_integral I>
static void describeField(Dict& obj) {
obj["type"] = "integer";
}

template <std::unsigned_integral I>
static void describeField(Dict& obj) {
obj["type"] = "integer";
}

template <std::floating_point F>
static void describeField(Dict& obj) {
obj["type"] = "number";
}

template <std::same_as<std::string> S>
static void describeField(Dict& obj) {
obj["type"] = "string";
}

template <std::same_as<bool> B>
static void describeField(Dict& obj) {
obj["type"] = "boolean";
}

template <std::same_as<std::nullptr_t> N>
static void describeField(Dict& obj) {
obj["type"] = "null";
}

template <Visitable V>
static void describeField(Dict& d) {
SchemaVisitor v(d);
V schema;
schema.visitFields(v);
}

template <typename Vec>
template <typename T>
static void describeField(Dict& obj) {
obj["type"] = "array";
describeField<typename Vec::value_type>(obj["items"]);
if constexpr (std::signed_integral<T> || std::unsigned_integral<T>) {
obj["type"] = "integer";
}
else if constexpr (std::floating_point<T>) {
obj["type"] = "number";
}
else if constexpr (std::same_as<T, std::string> || std::same_as<T, std::string_view>) {
obj["type"] = "string";
}
else if constexpr (std::same_as<T, bool>) {
obj["type"] = "boolean";
}
else if constexpr (std::same_as<T, std::nullptr_t>) {
obj["type"] = "null";
}
else if constexpr (Visitable<T>) {
SchemaVisitor v(obj);
T schema;
schema.visitFields(v);
}
else {
// assume array
obj["type"] = "array";
describeField<typename T::value_type>(obj["items"]);
}
}

template <typename T>
Expand Down

0 comments on commit d8af2d0

Please sign in to comment.