blob: 0fe34a7edc151dbe4ee5c02b8cb4ef57095cf262 [file] [log] [blame]
// 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.
#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