pw_string: Docs for choosing between InlineString and StringBuilder

- Add a section about how to choose between InlineString and
  StringBuilder.
- Emphasize that InlineString can be used to add null-terminators to
  length-delimited strings (std::string_view).

Change-Id: Ie45de936afc48dbbd134335d9a9765a8501e4789
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/109230
Commit-Queue: Wyatt Hepler <hepler@google.com>
Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com>
Reviewed-by: Ted Pudlik <tpudlik@google.com>
diff --git a/pw_string/docs.rst b/pw_string/docs.rst
index 2664561..d731939 100644
--- a/pw_string/docs.rst
+++ b/pw_string/docs.rst
@@ -83,13 +83,6 @@
   pw::InlineString<32> my_string = "Literally";
   my_string.append('?', 3);   // contains "Literally???"
 
-  // Like std::string, always null terminated when accessed through c_str().
-  if (std::fopen(my_string.c_str(), "r") == nullptr) {
-    // Integrates with std::string_view.
-    my_string = std::string_view("not\0literally", 12);
-    TakesAStringView(std::string_view(my_string));
-  }
-
   // Supports copying into known-capacity strings.
   pw::InlineString<64> other = my_string;
 
@@ -98,6 +91,16 @@
     other += my_string;
   }
 
+  // Like std::string, InlineString is always null terminated when accessed
+  // through c_str(). InlineString can be used to null-terminate
+  // length-delimited strings for APIs that expect null-terminated strings.
+  std::string_view file(".gif");
+  if (std::fopen(pw::InlineString<kMaxNameLen>(file).c_str(), "r") == nullptr) {
+    // Integrates with std::string_view.
+    my_string = std::string_view("not\0literally", 12);
+    TakesAStringView(std::string_view(my_string));
+  }
+
 All :cpp:type:`pw::InlineString` operations may be performed on strings without
 specifying their capacity.
 
@@ -304,6 +307,32 @@
 
   }  // namespace pw
 
+Choosing between InlineString and StringBuilder
+-----------------------------------------------
+:cpp:type:`pw::InlineString` is comparable to ``std::string``, while
+:cpp:class:`pw::StringBuilder` is comparable to ``std::ostringstream``.
+Because :cpp:class:`pw::StringBuilder` provides high-level stream functionality,
+it has more overhead than :cpp:type:`pw::InlineString`.
+
+Use :cpp:type:`pw::InlineString` unless :cpp:class:`pw::StringBuilder`'s
+capabilities are needed. Features unique to :cpp:class:`pw::StringBuilder`
+include:
+
+* Polymorphic C++ stream-style output, potentially supporting custom types.
+* Non-fatal handling of failed append/format operations.
+* Tracking the status of a series of operations.
+* Building a string in an external buffer.
+
+If those features are not required, use :cpp:type:`pw::InlineString`. A common
+example of when to prefer :cpp:type:`pw::InlineString` is wrapping a
+length-delimited string (e.g. ``std::string_view``) for APIs that require null
+termination.
+
+.. code-block:: cpp
+
+  void ProcessName(std::string_view name) {
+    PW_LOG_DEBUG("The name is %s", pw::InlineString<kMaxNameLen>(name).c_str());
+
 Size report: replacing snprintf with pw::StringBuilder
 ------------------------------------------------------
 StringBuilder is safe, flexible, and results in much smaller code size than