| // Copyright 2019 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CROS_DISKS_QUOTE_H_ |
| #define CROS_DISKS_QUOTE_H_ |
| |
| #include <ostream> |
| #include <string> |
| #include <utility> |
| |
| #include <base/files/file_path.h> |
| |
| namespace cros_disks { |
| |
| // Helper struct that holds a non-owning const reference to a T and allows to |
| // print a quoted version of it to an output stream. |
| // |
| // Don't use it directly. Call quote() instead. |
| template <typename T> |
| struct Quoter { |
| const T& ref; |
| }; |
| |
| // Allows to print a quoted version of its argument to an output stream for |
| // logging purpose. |
| // |
| // T must be a quotable type, ie a string, a FilePath or a vector of quotable |
| // elements. |
| // |
| // The returned Quoter should be streamed directly without being stored. |
| // The typical usage pattern is: |
| // |
| // LOG(ERROR) << "Cannot do something with " << quote(stuff) << ": Reason why"; |
| template <typename T> |
| Quoter<T> quote(const T& ref) { |
| return {ref}; |
| } |
| |
| // Outputs a quoted C-style string, or (null) for a null pointer. |
| std::ostream& operator<<(std::ostream& out, Quoter<const char*> quoter); |
| |
| // Outputs a quoted standard string. |
| std::ostream& operator<<(std::ostream& out, Quoter<std::string> quoter); |
| |
| // Outputs a quoted file path. |
| std::ostream& operator<<(std::ostream& out, Quoter<base::FilePath> quoter); |
| |
| // Outputs a quoted string literal. |
| // This is needed because quote("some string literal") doesn't decay the passed |
| // string literal to a const char* but keeps it as a reference to a const |
| // char[N]. |
| template <size_t N> |
| std::ostream& operator<<(std::ostream& out, Quoter<char[N]> quoter) { |
| const char* const s = quoter.ref; |
| return out << quote(s); |
| } |
| |
| // Outputs a sequence of quoted items. |
| template <typename T, typename = decltype(std::declval<const T&>().begin())> |
| std::ostream& operator<<(std::ostream& out, Quoter<T> quoter) { |
| out << '['; |
| const char* sep = ""; |
| for (const auto& item : quoter.ref) { |
| out << std::exchange(sep, ", ") << quote(item); |
| } |
| return out << ']'; |
| } |
| |
| } // namespace cros_disks |
| |
| #endif // CROS_DISKS_QUOTE_H_ |