Skip to content

Commit

Permalink
Adding colourizing utilities for making pretty output text.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 612208293
  • Loading branch information
jwhpryor authored and copybara-github committed Mar 5, 2024
1 parent 12a1c17 commit a67cc36
Show file tree
Hide file tree
Showing 6 changed files with 324 additions and 0 deletions.
19 changes: 19 additions & 0 deletions implementation/jni_helper/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,25 @@ licenses(["notice"])

exports_files(["LICENSE"])

################################################################################
# ArgPrint.
################################################################################
cc_library(
name = "arg_string",
hdrs = ["arg_string.h"],
deps = ["//:jni_dep"],
)

cc_test(
name = "arg_string_test",
srcs = ["arg_string_test.cc"],
deps = [
":arg_string",
"//:jni_dep",
"@googletest//:gtest_main",
],
)

################################################################################
# FieldValue.
################################################################################
Expand Down
75 changes: 75 additions & 0 deletions implementation/jni_helper/arg_string.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright 2024 Google LLC
*
* 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.
*/
#ifndef JNI_BIND_IMPLEMENTATION_JNI_HELPER_ARG_STRING_H_
#define JNI_BIND_IMPLEMENTATION_JNI_HELPER_ARG_STRING_H_

#include <sstream>
#include <string>

namespace jni {

// A basic default printer that uses `printf`.
template <typename T>
struct ArgStringify {
static std::string Str(const T& val) {
std::stringstream ss;
ss << val;

return ss.str();
}
};

template <typename T>
struct ArgStringify<T*> {
static std::string Str(const T* val) {
if (val == nullptr) {
return "nullptr";
}

std::stringstream ss;
ss << val;

return ss.str();
}
};

// Helper function to select correct ArgString partial specialization.
template <typename T>
std::string ArgString(const T& val) {
return ArgStringify<T>::Str(val);
}

////////////////////////////////////////////////////////////////////////////////
// Void.
////////////////////////////////////////////////////////////////////////////////
template <>
struct ArgStringify<void> {
static std::string Str() { return ""; }
};

inline std::string ArgString() { return ArgStringify<void>::Str(); }

////////////////////////////////////////////////////////////////////////////////
// Bool.
////////////////////////////////////////////////////////////////////////////////
template <>
struct ArgStringify<bool> {
static std::string Str(const bool val) { return val ? "TRUE" : "FALSE"; }
};

} // namespace jni

#endif // JNI_BIND_IMPLEMENTATION_JNI_HELPER_ARG_STRING_H_
91 changes: 91 additions & 0 deletions implementation/jni_helper/arg_string_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright 2024 Google LLC
*
* 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 "implementation/jni_helper/arg_string.h"

#include <limits>

#include <gtest/gtest.h>
#include "jni_dep.h"

using ::jni::ArgString;

namespace {

////////////////////////////////////////////////////////////////////////////////
// Void.
////////////////////////////////////////////////////////////////////////////////
TEST(ArgString, Void) { EXPECT_EQ(ArgString(), ""); }

////////////////////////////////////////////////////////////////////////////////
// Primitive Types.
////////////////////////////////////////////////////////////////////////////////
TEST(ArgString, Bool) {
EXPECT_EQ(ArgString(true), "TRUE");
EXPECT_EQ(ArgString(false), "FALSE");
}

TEST(ArgString, Char) {
EXPECT_EQ(ArgString('x'), "x");
EXPECT_EQ(ArgString('y'), "y");
EXPECT_EQ(ArgString('z'), "z");
}

TEST(ArgString, Short) {
EXPECT_EQ(ArgString(jshort{32767}), "32767");
EXPECT_EQ(ArgString(jshort{-32768}), "-32768");
EXPECT_EQ(ArgString(static_cast<jshort>(65535)), "-1"); // no unsigned
}

TEST(ArgString, Int) { EXPECT_EQ(ArgString(jint{-2147483648}), "-2147483648"); }

TEST(ArgString, Long) {
EXPECT_EQ(ArgString(jlong{9223372036854775807}), "9223372036854775807");
}

TEST(ArgString, Float) {
EXPECT_EQ(ArgString(jfloat{std::numeric_limits<float>::max()}),
"3.40282e+38");
}

TEST(ArgString, Double) {
EXPECT_EQ(ArgString(jdouble{std::numeric_limits<double>::max()}),
"1.79769e+308");
}

////////////////////////////////////////////////////////////////////////////////
// Pointers.
////////////////////////////////////////////////////////////////////////////////
TEST(ArgString, HandlesNullPointers) {
EXPECT_EQ(ArgString(reinterpret_cast<int*>(0)), "nullptr");
}

TEST(ArgString, Pointers) {
EXPECT_EQ(ArgString(reinterpret_cast<float*>(0XABCDEF)), "0xabcdef");
}

////////////////////////////////////////////////////////////////////////////////
// Char* (Strings).
////////////////////////////////////////////////////////////////////////////////
TEST(ArgString, NullForEmptyChar) {
EXPECT_EQ(ArgString(static_cast<char*>(nullptr)), "nullptr");
}

TEST(ArgString, ExplicitLengthArray) {
EXPECT_EQ(ArgString("fooBaz"), // Type is char[7].
"fooBaz");
}

} // namespace
17 changes: 17 additions & 0 deletions metaprogramming/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,23 @@ cc_test(
],
)

################################################################################
# color.
################################################################################
cc_library(
name = "color",
hdrs = ["color.h"],
)

cc_test(
name = "color_test",
srcs = ["color_test.cc"],
deps = [
":color",
"@googletest//:gtest_main",
],
)

################################################################################
# Concatenate.
################################################################################
Expand Down
76 changes: 76 additions & 0 deletions metaprogramming/color.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright 2024 Google LLC
*
* 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.
*/

#ifndef JNI_BIND_METAPROGRAMMING_COLOUR_H_
#define JNI_BIND_METAPROGRAMMING_COLOUR_H_

#include <string>
#include <string_view>

namespace jni::metaprogramming {

struct Color {
static constexpr std::string_view kNone{"\033[0m"};

// --- Text Colors ---
static constexpr std::string_view kBlack = "\033[0;30m";
static constexpr std::string_view kBlackBold = "\033[1;30m";
static constexpr std::string_view kRed = "\033[0;31m";
static constexpr std::string_view kRedBold = "\033[1;31m";
static constexpr std::string_view kGreen = "\033[0;32m";
static constexpr std::string_view kGreenBold = "\033[1;32m";
static constexpr std::string_view kYellow = "\033[0;33m";
static constexpr std::string_view kYellowBold = "\033[1;33m";
static constexpr std::string_view kBlue = "\033[0;34m";
static constexpr std::string_view kBlueBold = "\033[1;34m";
static constexpr std::string_view kPurple = "\033[0;35m";
static constexpr std::string_view kPurpleBold = "\033[1;35m";
static constexpr std::string_view kCyan = "\033[0;36m";
static constexpr std::string_view kCyanBold = "\033[1;36m";
static constexpr std::string_view kWhite = "\033[0;37m";
static constexpr std::string_view kWhiteBold = "\033[1;37m";

// --- Background Colors ---
static constexpr std::string_view kBgBlack = "\033[40m";
static constexpr std::string_view kBgBlackBold = "\033[100m";
static constexpr std::string_view kBgRed = "\033[41m";
static constexpr std::string_view kBgRedBold = "\033[101m";
static constexpr std::string_view kBgGreen = "\033[42m";
static constexpr std::string_view kBgGreenBold = "\033[102m";
static constexpr std::string_view kBgYellow = "\033[43m";
static constexpr std::string_view kBgYellowBold = "\033[103m";
static constexpr std::string_view kBgBlue = "\033[44m";
static constexpr std::string_view kBgBlueBold = "\033[104m";
static constexpr std::string_view kBgPurple = "\033[45m";
static constexpr std::string_view kBgPurpleBold = "\033[105m";
static constexpr std::string_view kBgCyan = "\033[46m";
static constexpr std::string_view kBgCyanBold = "\033[106m";
static constexpr std::string_view kBgWhite = "\033[47m";
static constexpr std::string_view kBgWhiteBold = "\033[107m";
};

// Colorize function for runtime manipulation of text. This is suitable when
// the string is unknowable until runtime.
inline std::string Colorize(std::string_view colour, std::string_view str,
bool colourize = true) {
return !colourize ? std::string{str}
: std::string{colour} + std::string{str} +
std::string{Color::kNone};
}

} // namespace jni::metaprogramming

#endif // JNI_BIND_METAPROGRAMMING_COLOUR_H_
46 changes: 46 additions & 0 deletions metaprogramming/color_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright 2024 Google LLC
*
* 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 "color.h"

#include <cstdio>
#include <string>

#include <gtest/gtest.h>

using ::jni::metaprogramming::Color;
using ::jni::metaprogramming::Colorize;

namespace {

TEST(ColorTest, HasBlue) {
std::string output = Colorize(Color::kBlue, "Blue words").data();

printf("%s\n", output.c_str());

EXPECT_TRUE(Colorize(Color::kBlue, "Blue words").find(Color::kBlue) !=
std::string::npos);
}

TEST(ColorTest, HasGreenAndDoesntBleed) {
std::string output = Colorize(Color::kRed, "Red words").data();
printf("%s, no color.\n", output.c_str());

EXPECT_TRUE(output.find(Color::kRed) != std::string::npos);
EXPECT_TRUE(output.find(Color::kNone) != std::string::npos);
}

} // namespace

0 comments on commit a67cc36

Please sign in to comment.