Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ cmake_minimum_required(VERSION 3.13)

project("SilKit")

# Root of the SIL Kit tree; used by components (e.g. SilKitYaml) to locate
# vendored sources independently of the current subdirectory.
set(SILKIT_TOP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")

option(SILKIT_BUILD_DEMOS "Build the SIL Kit Demos" ON)
option(SILKIT_BUILD_STATIC "Compile the SIL Kit as a static library" OFF)
option(SILKIT_BUILD_TESTS "Enable unit and integration tests for the SIL Kit" ON)
Expand Down Expand Up @@ -133,6 +137,10 @@ if(MINGW)
endif()
endif()

# Internal, self-contained YAML helper library (header-only). Must come before
# SilKit, which depends on it, and after ThirdParty, which provides rapidyaml.
add_subdirectory(SilKitYaml)

# Have both SIL Kit library and demo project in a single solution
add_subdirectory(SilKit)
if(SILKIT_BUILD_UTILITIES)
Expand All @@ -158,6 +166,7 @@ if(SILKIT_INSTALL_SOURCE)
${CMAKE_CURRENT_SOURCE_DIR}/cmake
${CMAKE_CURRENT_SOURCE_DIR}/Demos
${CMAKE_CURRENT_SOURCE_DIR}/SilKit
${CMAKE_CURRENT_SOURCE_DIR}/SilKitYaml
${CMAKE_CURRENT_SOURCE_DIR}/Utilities
DESTINATION ${INSTALL_SOURCE_DIR}
COMPONENT source
Expand Down
8 changes: 8 additions & 0 deletions SilKit/source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ if (TARGET rapidyaml)
)
endif()

if (TARGET SilKitYaml)
# Internal, header-only YAML helper. BUILD_INTERFACE only -- it is not
# installed and its symbols are not exported from the SIL Kit library.
target_link_libraries(I_SilKit
INTERFACE $<BUILD_INTERFACE:SilKitYaml>
)
endif()


add_library(O_SilKit_CreateParticipantImpl OBJECT
CreateParticipantImpl.hpp
Expand Down
4 changes: 2 additions & 2 deletions SilKit/source/config/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ add_library(O_SilKit_Config OBJECT
YamlWriter.hpp
YamlWriter.cpp

YamlParserUtils.hpp
YamlParserUtils.cpp
CapabilitiesParser.hpp
CapabilitiesParser.cpp

YamlValidator.hpp
YamlValidator.cpp
Expand Down
55 changes: 55 additions & 0 deletions SilKit/source/config/CapabilitiesParser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-FileCopyrightText: 2026 Vector Informatik GmbH
//
// SPDX-License-Identifier: MIT

#include "config/CapabilitiesParser.hpp"

#include "silkit/participant/exception.hpp"

#include "SilKitYaml/BasicYamlReader.hpp"
#include "SilKitYaml/YamlSerdes.hpp"

namespace VSilKit {

using ValueT = std::vector<std::map<std::string, std::string>>;

namespace {
struct CapabilityReader: SilKitYaml::BasicYamlReader<CapabilityReader>
{
using BasicYamlReader::BasicYamlReader;
void Read(ValueT& value)
{
if(!IsSequence())
{
throw SilKitYaml::YamlError{"First element in Capabilities string is not a sequence"};
}

if(_node.has_children())
{
for(auto&& i: _node.cchildren())
{
auto&& parser = MakeImpl(i);
if(!parser.IsMap())
{
throw SilKitYaml::YamlError{"Capabilities should be a sequence of map objects."};
}
std::map<std::string, std::string> element;
static_cast<SilKitYaml::BasicYamlReader<CapabilityReader>&>(parser).Read(element);
value.emplace_back(std::move(element));
}
}
}
};

} // end namespace
auto ParseCapabilities(const std::string& input) -> std::vector<std::map<std::string, std::string>>
{
try {
return SilKitYaml::Deserialize<ValueT, CapabilityReader>(input);
} catch(const SilKitYaml::YamlError& ex)
{
throw SilKit::ConfigurationError{ex.what()};
}
}

} // namespace VSilKit
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,9 @@
#include <string>
#include <vector>

#include "silkit/participant/exception.hpp"

#include "rapidyaml.hpp"

namespace VSilKit {

// Utility for parsing key-value lists for protocol capabilities
auto ParseCapabilities(const std::string& input) -> std::vector<std::map<std::string, std::string>>;

auto MakeConfigurationError(ryml::Location location, const std::string_view message) -> SilKit::ConfigurationError;

auto GetRapidyamlCallbacks() -> ryml::Callbacks;

} // namespace VSilKit
66 changes: 26 additions & 40 deletions SilKit/source/config/YamlParser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@

#include <string>

#include "silkit/participant/exception.hpp"

#include "config/YamlReader.hpp"
#include "config/YamlWriter.hpp"
#include "config/YamlParserUtils.hpp"

#include "SilKitYaml/YamlSerdes.hpp"

#include "rapidyaml.hpp"

Expand All @@ -17,67 +20,50 @@ namespace Config {

//////////////////////////////////////////////////////////////////////
// Configuration Parsing
//
// Thin wrappers around the generic SilKitYaml serdes templates, defaulting to the
// SilKit concrete reader/writer for the in-tree configuration types. They form
// the boundary that translates SilKitYaml::YamlError into the public
// SilKit::ConfigurationError, preserving SIL Kit's exception contract.
//////////////////////////////////////////////////////////////////////

template <typename T, typename R = VSilKit::YamlReader>
auto Deserialize(const std::string& input) -> T
{
if (input.empty())
{
return {};
}

const auto rapidyamlCallbacks = VSilKit::GetRapidyamlCallbacks();

ryml::ParserOptions options{};
options.locations(true);

ryml::EventHandlerTree eventHandler{};
auto parser = ryml::Parser(&eventHandler, options);
parser.reserve_locations(100u);
auto&& cinput = ryml::to_csubstr(input);
try
{
auto tree = ryml::parse_in_arena(&parser, cinput);

// Install the error-handling callbacks. This will nicely format errors and throw an exception.
tree.callbacks(rapidyamlCallbacks);

// Extract a reference to the root node of the document tree.
auto root = tree.crootref();

R reader{parser, root};
T result{};
reader.Read(result);
return result;
return SilKitYaml::Deserialize<T, R>(input);
}
catch (const std::exception& ex)
{
throw SilKit::ConfigurationError{ex.what()};
}
catch (...)
{
throw;
}
}


template <typename T, typename W = VSilKit::YamlWriter>
auto Serialize(const T& input) -> std::string
{
ryml::Tree t;
W writer{t.rootref()};
writer.Write(input);
return ryml::emitrs_yaml<std::string>(t);
try
{
return SilKitYaml::Serialize<T, W>(input);
}
catch (const std::exception& ex)
{
throw SilKit::ConfigurationError{ex.what()};
}
}

template <typename T, typename W = VSilKit::YamlWriter>
auto SerializeAsJson(const T& input) -> std::string
{
ryml::Tree t;
W writer{t.rootref()};
writer.Write(input);
return ryml::emitrs_json<std::string>(t);
try
{
return SilKitYaml::SerializeAsJson<T, W>(input);
}
catch (const std::exception& ex)
{
throw SilKit::ConfigurationError{ex.what()};
}
}

} // namespace Config
Expand Down
93 changes: 0 additions & 93 deletions SilKit/source/config/YamlParserUtils.cpp

This file was deleted.

Loading
Loading