blob: 50893ca6b7186750ae5cd18d8331633b95d72463 [file] [log] [blame]
#pragma once
#include <algorithm>
#include <array>
#include <optional>
#include <string>
#include <string_view>
#include <tuple>
#include <sdbusplus/exception.hpp>
#include <sdbusplus/message.hpp>
#include <sdbusplus/utility/dedup_variant.hpp>
<%
def setOfPropertyTypes():
return set(p.cppTypeParam(interface.name) for p in
interface.properties);
%>\
namespace sdbusplus::common::${interface.cppNamespace()}
{
struct ${interface.classname}
{
static constexpr auto interface = "${interface.name}";
% for e in interface.enums:
enum class ${e.name}
{
% for v in e.values:
${v.name},
% endfor
};
% endfor
% if interface.properties:
using PropertiesVariant = sdbusplus::utility::dedup_variant_t<
${",\n ".join(sorted(setOfPropertyTypes()))}>;
% endif \
% for p in interface.paths:
% if p.description:
/** ${p.description.strip()} */
% endif
% if len(p.segments) == 0:
static constexpr auto ${p.snake_case} = "${p.value}";
% else:
struct ${p.snake_case}
{
static constexpr auto value = "${p.value}";
% for s in p.segments:
% if s.description:
/** ${s.description.strip()} */
% endif
static constexpr auto ${s.snake_case} = "${s.value}";
% endfor
};
% endif
% endfor
% for s in interface.service_names:
% if s.description:
/** ${s.description.strip()} */
% endif
static constexpr auto ${s.snake_case} = "${s.value}";
% endfor
% for e in interface.enums:
/** @brief Convert a string to an appropriate enum value.
* @param[in] s - The string to convert in the form of
* "${interface.name}.<value name>"
* @return - The enum value.
*
* @note Throws if string is not a valid mapping.
*/
static ${e.name} convert${e.name}FromString(const std::string& s);
/** @brief Convert a string to an appropriate enum value.
* @param[in] s - The string to convert in the form of
* "${interface.name}.<value name>"
* @return - The enum value or std::nullopt
*/
static std::optional<${e.name}>
convertStringTo${e.name}(const std::string& s) noexcept;
/** @brief Convert an enum value to a string.
* @param[in] e - The enum to convert to a string.
* @return - The string conversion in the form of
* "${interface.name}.<value name>"
*/
static std::string convert${e.name}ToString(${e.name} e);
% endfor
};
% for e in interface.enums:
/* Specialization of sdbusplus::common::convertForMessage
* for enum-type ${interface.classname}::${e.name}.
*
* This converts from the enum to a constant string representing the enum.
*
* @param[in] e - Enum value to convert.
* @return string representing the name for the enum value.
*/
inline std::string convertForMessage(${interface.classname}::${e.name} e)
{
return ${interface.classname}::convert${e.name}ToString(e);
}
% endfor
% for e in interface.enums:
namespace details
{
using namespace std::literals::string_view_literals;
/** String to enum mapping for ${interface.classname}::${e.name} */
inline constexpr std::array mapping${interface.classname}${e.name} = {
% for v in e.values:
std::make_tuple("${interface.name}.${e.name}.${v.name}"sv,
${interface.classname}::${e.name}::${v.name} ),
% endfor
};
} // namespace details
inline auto ${interface.classname}::convertStringTo${e.name}(const std::string& s) noexcept
-> std::optional<${e.name}>
{
auto i = std::find_if(std::begin(details::mapping${interface.classname}${e.name}),
std::end(details::mapping${interface.classname}${e.name}),
[&s](auto& e){ return s == std::get<0>(e); } );
if (std::end(details::mapping${interface.classname}${e.name}) == i)
{
return std::nullopt;
}
else
{
return std::get<1>(*i);
}
}
inline auto ${interface.classname}::convert${e.name}FromString(const std::string& s) -> ${e.name}
{
auto r = convertStringTo${e.name}(s);
if (!r)
{
throw sdbusplus::exception::InvalidEnumString();
}
else
{
return *r;
}
}
inline std::string ${interface.classname}::convert${e.name}ToString(
${interface.classname}::${e.name} v)
{
auto i = std::find_if(std::begin(details::mapping${interface.classname}${e.name}),
std::end(details::mapping${interface.classname}${e.name}),
[v](auto& e){ return v == std::get<1>(e); });
if (i == std::end(details::mapping${interface.classname}${e.name}))
{
throw std::invalid_argument(std::to_string(static_cast<int>(v)));
}
return std::string(std::get<0>(*i));
}
% endfor
} // sdbusplus::common::${interface.cppNamespace()}
namespace sdbusplus::message::details
{
% for e in interface.enums:
template <>
struct convert_from_string<common::${interface.cppNamespacedClass()}::${e.name}>
{
static auto op(const std::string& value) noexcept
{
return common::${interface.cppNamespacedClass()}::
convertStringTo${e.name}(value);
}
};
template <>
struct convert_to_string<common::${interface.cppNamespacedClass()}::${e.name}>
{
static std::string
op(common::${interface.cppNamespacedClass()}::${e.name} value)
{
return common::${interface.cppNamespacedClass()}::
convert${e.name}ToString(value);
}
};
% endfor
} // namespace sdbusplus::message::details