Skip to content
Open
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
26 changes: 23 additions & 3 deletions runtime/standard/type_conversion_functions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@

#include "runtime/standard/type_conversion_functions.h"

#include <charconv>
#include <cstdint>
#include <string>
#include <system_error> // NOLINT (required for std::to_chars_result)
#include <utility>

#include "absl/status/status.h"
Expand All @@ -41,6 +44,19 @@ using ::cel::internal::EncodeTimestampToJson;
using ::cel::internal::MaxTimestamp;
using ::cel::internal::MinTimestamp;

absl::StatusOr<std::string> FormatDouble(double v) {
constexpr int kBufSize = 32;
char buf[kBufSize];
std::to_chars_result result =
std::to_chars(buf, buf + kBufSize, v, std::chars_format::general);
if (result.ec != std::errc()) {
return absl::InvalidArgumentError(absl::StrCat(
"double format error: ", std::make_error_code(result.ec).message()));
}
std::string out(buf, result.ptr);
return out;
}

absl::Status RegisterBoolConversionFunctions(FunctionRegistry& registry,
const RuntimeOptions&) {
// bool -> bool
Expand Down Expand Up @@ -162,10 +178,14 @@ absl::Status RegisterStringConversionFunctions(FunctionRegistry& registry,
CEL_RETURN_IF_ERROR(status);

// double -> string
status = UnaryFunctionAdapter<StringValue, double>::RegisterGlobalOverload(
status = UnaryFunctionAdapter<Value, double>::RegisterGlobalOverload(
cel::builtin::kString,
[](double value) -> StringValue {
return StringValue(absl::StrCat(value));
[](double value) -> Value {
auto formatted = FormatDouble(value);
if (!formatted.ok()) {
return ErrorValue(std::move(formatted).status());
}
return StringValue(*std::move(formatted));
},
registry);
CEL_RETURN_IF_ERROR(status);
Expand Down
6 changes: 6 additions & 0 deletions runtime/standard_runtime_builder_factory_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,10 @@ INSTANTIATE_TEST_SUITE_P(
{"string_int", "string(-1) == '-1'", true},
{"string_uint", "string(1u) == '1'", true},
{"string_double", "string(double('inf')) == 'inf'", true},
{"string_double_nan", "string(double('nan')) == 'nan'", true},
{"string_double_precision",
"string(double('1.4285714285714285e-96')) == '1.4285714285714285e-96'",
true},
{"string_bytes", R"(string(b'\xF0\x9F\x98\x80') == '😀')", true},
{"string_string", "string('hello!') == 'hello!'", true},
{"bytes_bytes", "bytes(b'123') == b'123'", true},
Expand All @@ -483,6 +487,8 @@ INSTANTIATE_TEST_SUITE_P(
true},
{"duration", "duration('10h') == duration('600m')", true},
{"double_string", "double('1.0') == 1.0", true},
{"double_string_precision",
"double('0.14285714285714285') == 1.0 / 7.0", true},
{"double_string_nan", "double('nan') != double('nan')", true},
{"double_int", "double(1) == 1.0", true},
{"double_uint", "double(1u) == 1.0", true},
Expand Down