Skip to content

Commit

Permalink
fmt_vformat_mangle_name, fmt_vformat_mangle_format_string
Browse files Browse the repository at this point in the history
Summary: So that we can use format-strings with named-args outside of the regime directly supported by `fmt::vformat`.

Reviewed By: Gownta

Differential Revision: D67320144

fbshipit-source-id: 3685d8115008d88b82deb82b774e274dea350022
  • Loading branch information
yfeldblum authored and facebook-github-bot committed Dec 19, 2024
1 parent ad12236 commit 819b4c4
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 1 deletion.
8 changes: 8 additions & 0 deletions folly/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -568,9 +568,17 @@ cpp_library(

cpp_library(
name = "fmt_utility",
srcs = [
"FmtUtility.cpp",
],
headers = [
"FmtUtility.h",
],
deps = [
":range",
":string",
"//folly/ssl:openssl_hash",
],
exported_deps = [
"fbsource//third-party/fmt:fmt",
":cpp_attributes",
Expand Down
60 changes: 60 additions & 0 deletions folly/FmtUtility.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <folly/FmtUtility.h>

#include <folly/Range.h>
#include <folly/String.h>
#include <folly/ssl/OpenSSLHash.h>

namespace folly {

std::string fmt_vformat_mangle_name_fn::operator()(
std::string_view const key) const {
auto& self = *this;
std::string out;
self(out, key);
return out;
}

void fmt_vformat_mangle_name_fn::operator()(
std::string& out, std::string_view const key) const {
auto const keyr = folly::ByteRange(folly::StringPiece(key));
uint8_t enc[32];
auto const encr = folly::MutableByteRange{std::begin(enc), std::end(enc)};
#if FOLLY_OPENSSL_HAS_BLAKE2B
folly::ssl::OpenSSLHash::blake2s256(encr, keyr);
#else
folly::ssl::OpenSSLHash::sha256(encr, keyr);
#endif
out.push_back('_');
folly::hexlify(encr, out, true);
}

std::string fmt_vformat_mangle_format_string_fn::operator()(
std::string_view const str) const {
std::string out;
char const* pos = str.data();
format_string_for_each_named_arg(str, [&](auto const arg) {
out.append(pos, arg.data());
fmt_vformat_mangle_name(out, arg);
pos = arg.data() + arg.size();
});
out.append(pos, str.data() + str.size());
return out;
}

} // namespace folly
23 changes: 23 additions & 0 deletions folly/FmtUtility.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,27 @@ struct fmt_make_format_args_from_map_fn {
inline constexpr fmt_make_format_args_from_map_fn
fmt_make_format_args_from_map{};

/// fmt_vformat_mangle_name_fn
/// fmt_vformat_mangle_name
///
/// A helper function-object type and variable for mangling vformat named-arg
/// names which fmt::vformat might not otherwise permit.
struct fmt_vformat_mangle_name_fn {
std::string operator()(std::string_view const str) const;
void operator()(std::string& out, std::string_view const str) const;
};
inline constexpr fmt_vformat_mangle_name_fn fmt_vformat_mangle_name{};

/// fmt_vformat_mangle_format_string_fn
/// fmt_vformat_mangle_format_string
///
/// A helper function-object type and variable for mangling the content of
/// vformat format-strings containing named-arg names which fmt::vformat might
/// not otherwise permit.
struct fmt_vformat_mangle_format_string_fn {
std::string operator()(std::string_view const str) const;
};
inline constexpr fmt_vformat_mangle_format_string_fn
fmt_vformat_mangle_format_string{};

} // namespace folly
2 changes: 1 addition & 1 deletion folly/String.h
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ struct format_string_for_each_named_arg_fn {
}
auto const arg = str.substr(beg, end - beg);
auto const c = arg.empty() ? 0 : arg[0];
if (c == '_' || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
if (c && !(c >= '0' && c <= '9')) {
fn(arg);
}
str = str.substr(end);
Expand Down
13 changes: 13 additions & 0 deletions folly/test/FmtUtilityTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,16 @@ TEST_F(FmtUtilityTest, fmt_make_format_args_from_map_fn) {
{"adj"s, "silly"sv},
})));
}

TEST_F(FmtUtilityTest, fmt_vformat_mangle) {
EXPECT_EQ(
"hello bob you silly goose",
fmt::vformat(
folly::fmt_vformat_mangle_format_string(
"hello {@pre-key|name} you {@pre-key|adj} goose"),
folly::fmt_make_format_args_from_map(
std::map<std::string, std::string_view>{
{folly::fmt_vformat_mangle_name("@pre-key|name"), "bob"sv},
{folly::fmt_vformat_mangle_name("@pre-key|adj"), "silly"sv},
})));
}

0 comments on commit 819b4c4

Please sign in to comment.