Refactor intrinThresholdParams to use shared DAP helpers.
Delegate threshold param parsing to the new DeviceAttachmentSpec primitives so intrin modules stay aligned with stimBuff param conventions. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -19,3 +19,25 @@ add_dependencies(deviceAttachmentSpecParams_tests gtest_main)
|
|||||||
add_test(
|
add_test(
|
||||||
NAME deviceAttachmentSpecParams_tests
|
NAME deviceAttachmentSpecParams_tests
|
||||||
COMMAND deviceAttachmentSpecParams_tests)
|
COMMAND deviceAttachmentSpecParams_tests)
|
||||||
|
|
||||||
|
add_executable(intrinThresholdParams_tests
|
||||||
|
intrinThresholdParams_tests.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(intrinThresholdParams_tests PRIVATE
|
||||||
|
${CMAKE_SOURCE_DIR}/include
|
||||||
|
${CMAKE_BINARY_DIR}/include
|
||||||
|
${CMAKE_SOURCE_DIR}/libspinscale/tests
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(intrinThresholdParams_tests
|
||||||
|
gtest_main
|
||||||
|
spinscale_test_support
|
||||||
|
${Boost_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_dependencies(intrinThresholdParams_tests gtest_main)
|
||||||
|
|
||||||
|
add_test(
|
||||||
|
NAME intrinThresholdParams_tests
|
||||||
|
COMMAND intrinThresholdParams_tests)
|
||||||
|
|||||||
@@ -0,0 +1,331 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <support/exceptionAssertions.h>
|
||||||
|
#include <user/intrinThresholdParams.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace smo {
|
||||||
|
namespace intrin {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using ParamList = std::vector<std::pair<std::string, std::string>>;
|
||||||
|
|
||||||
|
ParamList makeParams(std::initializer_list<std::pair<const char*, const char*>> entries)
|
||||||
|
{
|
||||||
|
ParamList params;
|
||||||
|
for (const auto& entry : entries)
|
||||||
|
{
|
||||||
|
params.emplace_back(entry.first, entry.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdArrayContainsTest, MatchesCanonicalNames)
|
||||||
|
{
|
||||||
|
EXPECT_TRUE(arrayContains(kIntrinInterestPcNames, "interest-pc"));
|
||||||
|
EXPECT_TRUE(arrayContains(kIntrinInterestThrNames, "interest-thr"));
|
||||||
|
EXPECT_FALSE(arrayContains(kForbiddenUnitlessIntrinStems, "interest-pc"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdIsKnownParamNameTest, RecognizesAllCanonicalFamilies)
|
||||||
|
{
|
||||||
|
EXPECT_TRUE(isKnownIntrinThresholdParamName("interest-pc"));
|
||||||
|
EXPECT_TRUE(isKnownIntrinThresholdParamName("interest-threshold"));
|
||||||
|
EXPECT_TRUE(isKnownIntrinThresholdParamName("distraction-percentage"));
|
||||||
|
EXPECT_TRUE(isKnownIntrinThresholdParamName("distraction-thr"));
|
||||||
|
EXPECT_TRUE(isKnownIntrinThresholdParamName("stupefying-pc"));
|
||||||
|
EXPECT_TRUE(isKnownIntrinThresholdParamName("stupefaction-thresh"));
|
||||||
|
EXPECT_TRUE(isKnownIntrinThresholdParamName("intolerable-pc"));
|
||||||
|
EXPECT_TRUE(isKnownIntrinThresholdParamName("intolerable-threshold"));
|
||||||
|
|
||||||
|
EXPECT_FALSE(isKnownIntrinThresholdParamName("interest"));
|
||||||
|
EXPECT_FALSE(isKnownIntrinThresholdParamName("passband-count-gt-val"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdValidateNoIntrinParamsOnQualeIfaceTest, RejectsKnownIntrinNames)
|
||||||
|
{
|
||||||
|
const ParamList params = makeParams({{"interest-pc", "85"}});
|
||||||
|
|
||||||
|
try {
|
||||||
|
validateNoIntrinParamsOnQualeIface("pcloudLightAmbience", params);
|
||||||
|
FAIL() << "Expected std::runtime_error";
|
||||||
|
}
|
||||||
|
catch (const std::runtime_error& exception)
|
||||||
|
{
|
||||||
|
sscl::tests::expectExceptionMessageContains(
|
||||||
|
exception, "not valid on qualeIfaceApi");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdValidateNoIntrinParamsOnQualeIfaceTest, RejectsUnitlessStems)
|
||||||
|
{
|
||||||
|
const ParamList params = makeParams({{"distraction", "10"}});
|
||||||
|
|
||||||
|
try {
|
||||||
|
validateNoIntrinParamsOnQualeIface("mesh", params);
|
||||||
|
FAIL() << "Expected std::runtime_error";
|
||||||
|
}
|
||||||
|
catch (const std::runtime_error& exception)
|
||||||
|
{
|
||||||
|
sscl::tests::expectExceptionMessageContains(
|
||||||
|
exception, "invalid without a unit suffix");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdValidateNoIntrinParamsOnQualeIfaceTest, RejectsFromStimbuffMarker)
|
||||||
|
{
|
||||||
|
const ParamList params = makeParams({{"from-stimbuff", ""}});
|
||||||
|
|
||||||
|
try {
|
||||||
|
validateNoIntrinParamsOnQualeIface("mesh", params);
|
||||||
|
FAIL() << "Expected std::runtime_error";
|
||||||
|
}
|
||||||
|
catch (const std::runtime_error& exception)
|
||||||
|
{
|
||||||
|
sscl::tests::expectExceptionMessageContains(
|
||||||
|
exception, "from-stimbuff");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdValidateNoIntrinParamsOnQualeIfaceTest, AllowsSensoryParams)
|
||||||
|
{
|
||||||
|
const ParamList params = makeParams({
|
||||||
|
{"passband-count-gt-val", "12"},
|
||||||
|
{"histbuff-ms", "30000"},
|
||||||
|
});
|
||||||
|
|
||||||
|
EXPECT_NO_THROW(validateNoIntrinParamsOnQualeIface(
|
||||||
|
"pcloudLightAmbience", params));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdValidateIntrinSegmentParamsTest, RejectsUnitlessStems)
|
||||||
|
{
|
||||||
|
const ParamList params = makeParams({{"stupefaction", "5"}});
|
||||||
|
|
||||||
|
try {
|
||||||
|
validateIntrinSegmentParams("postrin", params);
|
||||||
|
FAIL() << "Expected std::runtime_error";
|
||||||
|
}
|
||||||
|
catch (const std::runtime_error& exception)
|
||||||
|
{
|
||||||
|
sscl::tests::expectExceptionMessageContains(
|
||||||
|
exception, "invalid without a unit suffix");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdValidateIntrinSegmentParamsTest, AllowsSuffixedNames)
|
||||||
|
{
|
||||||
|
const ParamList params = makeParams({
|
||||||
|
{"interest-pc", "85"},
|
||||||
|
{"distraction-thr", "12"},
|
||||||
|
});
|
||||||
|
|
||||||
|
EXPECT_NO_THROW(validateIntrinSegmentParams("negtrin", params));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdParseOptionalThresholdParamTest, ReturnsDefaultWhenAbsent)
|
||||||
|
{
|
||||||
|
const ParamList params = makeParams({{"other-param", "1"}});
|
||||||
|
|
||||||
|
const ParsedThresholdParam parsed = parseOptionalThresholdParam(
|
||||||
|
params,
|
||||||
|
kIntrinInterestPcNames,
|
||||||
|
kIntrinInterestThrNames,
|
||||||
|
/*defaultValue=*/7,
|
||||||
|
/*defaultUnit=*/ThresholdUnit::Absolute);
|
||||||
|
|
||||||
|
EXPECT_FALSE(parsed.wasSpecified);
|
||||||
|
EXPECT_EQ(parsed.value, 7);
|
||||||
|
EXPECT_EQ(parsed.unit, ThresholdUnit::Absolute);
|
||||||
|
EXPECT_TRUE(parsed.matchedName.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdParseOptionalThresholdParamTest, ParsesPercentageParam)
|
||||||
|
{
|
||||||
|
const ParamList params = makeParams({{"interest-percentage", "50"}});
|
||||||
|
|
||||||
|
const ParsedThresholdParam parsed = parseOptionalThresholdParam(
|
||||||
|
params,
|
||||||
|
kIntrinInterestPcNames,
|
||||||
|
kIntrinInterestThrNames,
|
||||||
|
0,
|
||||||
|
ThresholdUnit::Absolute);
|
||||||
|
|
||||||
|
EXPECT_TRUE(parsed.wasSpecified);
|
||||||
|
EXPECT_EQ(parsed.value, 50);
|
||||||
|
EXPECT_EQ(parsed.unit, ThresholdUnit::Percentage);
|
||||||
|
EXPECT_EQ(parsed.matchedName, "interest-percentage");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdParseOptionalThresholdParamTest, ParsesAbsoluteParam)
|
||||||
|
{
|
||||||
|
const ParamList params = makeParams({{"interest-threshold", "42"}});
|
||||||
|
|
||||||
|
const ParsedThresholdParam parsed = parseOptionalThresholdParam(
|
||||||
|
params,
|
||||||
|
kIntrinInterestPcNames,
|
||||||
|
kIntrinInterestThrNames,
|
||||||
|
0,
|
||||||
|
ThresholdUnit::Percentage);
|
||||||
|
|
||||||
|
EXPECT_TRUE(parsed.wasSpecified);
|
||||||
|
EXPECT_EQ(parsed.value, 42);
|
||||||
|
EXPECT_EQ(parsed.unit, ThresholdUnit::Absolute);
|
||||||
|
EXPECT_EQ(parsed.matchedName, "interest-threshold");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdParseOptionalThresholdParamTest, LattermostMatchingParamWins)
|
||||||
|
{
|
||||||
|
const ParamList params = makeParams({
|
||||||
|
{"interest-pc", "10"},
|
||||||
|
{"interest-threshold", "99"},
|
||||||
|
});
|
||||||
|
|
||||||
|
const ParsedThresholdParam parsed = parseOptionalThresholdParam(
|
||||||
|
params,
|
||||||
|
kIntrinInterestPcNames,
|
||||||
|
kIntrinInterestThrNames,
|
||||||
|
0,
|
||||||
|
ThresholdUnit::Percentage);
|
||||||
|
|
||||||
|
EXPECT_TRUE(parsed.wasSpecified);
|
||||||
|
EXPECT_EQ(parsed.value, 99);
|
||||||
|
EXPECT_EQ(parsed.unit, ThresholdUnit::Absolute);
|
||||||
|
EXPECT_EQ(parsed.matchedName, "interest-threshold");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdParseOptionalThresholdParamTest, LattermostPercentageWinsOverEarlierAbsolute)
|
||||||
|
{
|
||||||
|
const ParamList params = makeParams({
|
||||||
|
{"interest-thr", "12"},
|
||||||
|
{"interest-pc", "75"},
|
||||||
|
});
|
||||||
|
|
||||||
|
const ParsedThresholdParam parsed = parseOptionalThresholdParam(
|
||||||
|
params,
|
||||||
|
kIntrinInterestPcNames,
|
||||||
|
kIntrinInterestThrNames,
|
||||||
|
0,
|
||||||
|
ThresholdUnit::Absolute);
|
||||||
|
|
||||||
|
EXPECT_TRUE(parsed.wasSpecified);
|
||||||
|
EXPECT_EQ(parsed.value, 75);
|
||||||
|
EXPECT_EQ(parsed.unit, ThresholdUnit::Percentage);
|
||||||
|
EXPECT_EQ(parsed.matchedName, "interest-pc");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdParseOptionalThresholdParamTest, InvalidIntegerThrows)
|
||||||
|
{
|
||||||
|
const ParamList params = makeParams({{"interest-pc", "not-int"}});
|
||||||
|
|
||||||
|
try {
|
||||||
|
parseOptionalThresholdParam(
|
||||||
|
params,
|
||||||
|
kIntrinInterestPcNames,
|
||||||
|
kIntrinInterestThrNames,
|
||||||
|
0,
|
||||||
|
ThresholdUnit::Absolute);
|
||||||
|
FAIL() << "Expected std::runtime_error";
|
||||||
|
}
|
||||||
|
catch (const std::runtime_error& exception)
|
||||||
|
{
|
||||||
|
sscl::tests::expectExceptionMessageContains(
|
||||||
|
exception, "Failed to parse 'interest-pc'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdResolveThresholdValueTest, PercentageUsesBase)
|
||||||
|
{
|
||||||
|
const ParsedThresholdParam percentageParam = {
|
||||||
|
.value = 50,
|
||||||
|
.unit = ThresholdUnit::Percentage,
|
||||||
|
.matchedName = "interest-pc",
|
||||||
|
.wasSpecified = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPECT_EQ(resolveThresholdValue(percentageParam, 84), 42u);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdResolveThresholdValueTest, AbsolutePassesThrough)
|
||||||
|
{
|
||||||
|
const ParsedThresholdParam absoluteParam = {
|
||||||
|
.value = 17,
|
||||||
|
.unit = ThresholdUnit::Absolute,
|
||||||
|
.matchedName = "interest-thr",
|
||||||
|
.wasSpecified = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPECT_EQ(resolveThresholdValue(absoluteParam, 84), 17u);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdResolveThresholdValueTest, PercentageTruncatesTowardZero)
|
||||||
|
{
|
||||||
|
const ParsedThresholdParam percentageParam = {
|
||||||
|
.value = 33,
|
||||||
|
.unit = ThresholdUnit::Percentage,
|
||||||
|
.matchedName = "interest-pc",
|
||||||
|
.wasSpecified = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPECT_EQ(resolveThresholdValue(percentageParam, 100), 33u);
|
||||||
|
EXPECT_EQ(resolveThresholdValue(percentageParam, 10), 3u);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdSynonymCoverageTest, AllThrSynonymsParseAsAbsolute)
|
||||||
|
{
|
||||||
|
const std::array<std::string_view, 3> thrNames = {
|
||||||
|
"interest-threshold",
|
||||||
|
"interest-thresh",
|
||||||
|
"interest-thr",
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const std::string_view thrName : thrNames)
|
||||||
|
{
|
||||||
|
const ParamList params = makeParams({
|
||||||
|
{thrName.data(), "11"},
|
||||||
|
});
|
||||||
|
|
||||||
|
const ParsedThresholdParam parsed = parseOptionalThresholdParam(
|
||||||
|
params,
|
||||||
|
kIntrinInterestPcNames,
|
||||||
|
kIntrinInterestThrNames,
|
||||||
|
0,
|
||||||
|
ThresholdUnit::Percentage);
|
||||||
|
|
||||||
|
EXPECT_TRUE(parsed.wasSpecified);
|
||||||
|
EXPECT_EQ(parsed.unit, ThresholdUnit::Absolute);
|
||||||
|
EXPECT_EQ(parsed.value, 11);
|
||||||
|
EXPECT_EQ(parsed.matchedName, thrName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(IntrinThresholdSynonymCoverageTest, AllPcSynonymsParseAsPercentage)
|
||||||
|
{
|
||||||
|
const std::array<std::string_view, 2> pcNames = {
|
||||||
|
"interest-percentage",
|
||||||
|
"interest-pc",
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const std::string_view pcName : pcNames)
|
||||||
|
{
|
||||||
|
const ParamList params = makeParams({
|
||||||
|
{pcName.data(), "25"},
|
||||||
|
});
|
||||||
|
|
||||||
|
const ParsedThresholdParam parsed = parseOptionalThresholdParam(
|
||||||
|
params,
|
||||||
|
kIntrinInterestPcNames,
|
||||||
|
kIntrinInterestThrNames,
|
||||||
|
0,
|
||||||
|
ThresholdUnit::Absolute);
|
||||||
|
|
||||||
|
EXPECT_TRUE(parsed.wasSpecified);
|
||||||
|
EXPECT_EQ(parsed.unit, ThresholdUnit::Percentage);
|
||||||
|
EXPECT_EQ(parsed.value, 25);
|
||||||
|
EXPECT_EQ(parsed.matchedName, pcName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace intrin
|
||||||
|
} // namespace smo
|
||||||
@@ -11,6 +11,8 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <user/deviceAttachmentSpec.h>
|
||||||
|
|
||||||
namespace smo::intrin {
|
namespace smo::intrin {
|
||||||
|
|
||||||
enum class ThresholdUnit
|
enum class ThresholdUnit
|
||||||
@@ -97,35 +99,21 @@ inline bool arrayContains(
|
|||||||
const std::array<std::string_view, N>& names,
|
const std::array<std::string_view, N>& names,
|
||||||
std::string_view candidate)
|
std::string_view candidate)
|
||||||
{
|
{
|
||||||
for (const auto& name : names) {
|
return device::DeviceAttachmentSpec::namesContain(names, candidate);
|
||||||
if (name == candidate) { return true; }
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename NameCollectionT>
|
|
||||||
inline bool namesContain(
|
|
||||||
const NameCollectionT& names,
|
|
||||||
std::string_view candidate)
|
|
||||||
{
|
|
||||||
for (const auto& name : names) {
|
|
||||||
if (name == candidate) { return true; }
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isKnownIntrinThresholdParamName(std::string_view name)
|
inline bool isKnownIntrinThresholdParamName(std::string_view name)
|
||||||
{
|
{
|
||||||
return namesContain(kIntrinInterestPcNames, name)
|
using device::DeviceAttachmentSpec;
|
||||||
|| namesContain(kIntrinInterestThrNames, name)
|
|
||||||
|| namesContain(kIntrinDistractionPcNames, name)
|
return DeviceAttachmentSpec::namesContain(kIntrinInterestPcNames, name)
|
||||||
|| namesContain(kIntrinDistractionThrNames, name)
|
|| DeviceAttachmentSpec::namesContain(kIntrinInterestThrNames, name)
|
||||||
|| namesContain(kIntrinStupefactionPcNames, name)
|
|| DeviceAttachmentSpec::namesContain(kIntrinDistractionPcNames, name)
|
||||||
|| namesContain(kIntrinStupefactionThrNames, name)
|
|| DeviceAttachmentSpec::namesContain(kIntrinDistractionThrNames, name)
|
||||||
|| namesContain(kIntrinIntolerablePcNames, name)
|
|| DeviceAttachmentSpec::namesContain(kIntrinStupefactionPcNames, name)
|
||||||
|| namesContain(kIntrinIntolerableThrNames, name);
|
|| DeviceAttachmentSpec::namesContain(kIntrinStupefactionThrNames, name)
|
||||||
|
|| DeviceAttachmentSpec::namesContain(kIntrinIntolerablePcNames, name)
|
||||||
|
|| DeviceAttachmentSpec::namesContain(kIntrinIntolerableThrNames, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Intrin threshold params (interest-*, distraction-*, stupefaction-*,
|
/* Intrin threshold params (interest-*, distraction-*, stupefaction-*,
|
||||||
@@ -194,30 +182,6 @@ inline void validateIntrinSegmentParams(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::optional<std::pair<std::string_view, int>> findLastMatchingIntParam(
|
|
||||||
const std::vector<std::pair<std::string, std::string>>& params,
|
|
||||||
const auto& synonymNames)
|
|
||||||
{
|
|
||||||
for (auto paramIt = params.rbegin(); paramIt != params.rend(); ++paramIt)
|
|
||||||
{
|
|
||||||
const auto& [name, value] = *paramIt;
|
|
||||||
if (!namesContain(synonymNames, name))
|
|
||||||
{ continue; }
|
|
||||||
|
|
||||||
try {
|
|
||||||
return std::pair<std::string_view, int>(name, std::stoi(value));
|
|
||||||
}
|
|
||||||
catch (const std::exception& e)
|
|
||||||
{
|
|
||||||
throw std::runtime_error(
|
|
||||||
"Failed to parse '" + name + "' param value '" + value
|
|
||||||
+ "' as integer: " + e.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ParsedThresholdParam parseOptionalThresholdParam(
|
inline ParsedThresholdParam parseOptionalThresholdParam(
|
||||||
const std::vector<std::pair<std::string, std::string>>& params,
|
const std::vector<std::pair<std::string, std::string>>& params,
|
||||||
const auto& percentageNames,
|
const auto& percentageNames,
|
||||||
@@ -230,28 +194,20 @@ inline ParsedThresholdParam parseOptionalThresholdParam(
|
|||||||
const auto& [name, value] = *paramIt;
|
const auto& [name, value] = *paramIt;
|
||||||
ThresholdUnit unit;
|
ThresholdUnit unit;
|
||||||
|
|
||||||
if (namesContain(percentageNames, name))
|
if (device::DeviceAttachmentSpec::namesContain(percentageNames, name))
|
||||||
{ unit = ThresholdUnit::Percentage; }
|
{ unit = ThresholdUnit::Percentage; }
|
||||||
else if (namesContain(absoluteNames, name))
|
else if (device::DeviceAttachmentSpec::namesContain(absoluteNames, name))
|
||||||
{ unit = ThresholdUnit::Absolute; }
|
{ unit = ThresholdUnit::Absolute; }
|
||||||
else
|
else
|
||||||
{ continue; }
|
{ continue; }
|
||||||
|
|
||||||
try
|
return ParsedThresholdParam{
|
||||||
{
|
.value = device::DeviceAttachmentSpec::parseParamValueAsInt(
|
||||||
return ParsedThresholdParam{
|
name, value),
|
||||||
.value = std::stoi(value),
|
.unit = unit,
|
||||||
.unit = unit,
|
.matchedName = name,
|
||||||
.matchedName = name,
|
.wasSpecified = true,
|
||||||
.wasSpecified = true,
|
};
|
||||||
};
|
|
||||||
}
|
|
||||||
catch (const std::exception& e)
|
|
||||||
{
|
|
||||||
throw std::runtime_error(
|
|
||||||
"Failed to parse '" + name + "' param value '" + value
|
|
||||||
+ "' as integer: " + e.what());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParsedThresholdParam{
|
return ParsedThresholdParam{
|
||||||
|
|||||||
Reference in New Issue
Block a user