pw_string: Improve StringBuilder hex support

Updates StringBuilder to format byte spans and byte arrays as hex
strings, and changes the std::byte ToString() overload such that it will
always emit full-width bytes (e.g. 04 instead of 4).

Change-Id: Iba5b7b81d190e9953424abd24f639134095cbd46
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/70183
Pigweed-Auto-Submit: Armando Montanez <amontanez@google.com>
Commit-Queue: Wyatt Hepler <hepler@google.com>
Reviewed-by: Ewout van Bekkum <ewout@google.com>
Reviewed-by: Wyatt Hepler <hepler@google.com>
diff --git a/pw_string/string_builder_test.cc b/pw_string/string_builder_test.cc
index a1686ac..d6f114c 100644
--- a/pw_string/string_builder_test.cc
+++ b/pw_string/string_builder_test.cc
@@ -379,6 +379,23 @@
   EXPECT_STREQ("hi!", buffer.data());
 }
 
+TEST(StringBuilder, StreamOutput_ByteSpan) {
+  StringBuffer<7> buffer;
+  std::array<std::byte, 3> data{
+      {std::byte(0xc8), std::byte(0x02), std::byte(0x41)}};
+  buffer << data;
+  EXPECT_EQ(buffer.status(), OkStatus());
+  EXPECT_STREQ("c80241", buffer.data());
+}
+
+TEST(StringBuilder, StreamOutput_ByteSpanOutOfSpace) {
+  StringBuffer<4> buffer;
+  std::array<uint8_t, 3> data{{0xc8, 0x02, 0x41}};
+  buffer << as_bytes(std::span(data));
+  EXPECT_EQ(buffer.status(), Status::ResourceExhausted());
+  EXPECT_STREQ("", buffer.data());
+}
+
 TEST(StringBuffer, Assign) {
   StringBuffer<10> one;
   StringBuffer<10> two;