blob: 62d2ebb76d2821b33fce824f4c606abc4d4d9623 [file] [log] [blame]
Dominik Laskowskie70461a2022-08-30 14:42:01 -07001/*
2 * Copyright 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
Dominik Laskowskie70461a2022-08-30 14:42:01 -070019#include <string>
20#include <string_view>
21
Dominik Laskowski03cfce82022-11-02 12:13:29 -040022#include <ftl/optional.h>
23
Dominik Laskowskie70461a2022-08-30 14:42:01 -070024namespace android::utils {
25
26// Dumps variables by appending their name and value to the output string. A variable is formatted
27// as "name=value". If the name or value is empty, the format is "value" or "name=", respectively.
28// A value of user-defined type T is stringified via `std::string to_string(const T&)`, which must
29// be defined in the same namespace as T per the rules of ADL (argument-dependent lookup).
30//
31// TODO(b/249828573): Consolidate with <compositionengine/impl/DumpHelpers.h>
32class Dumper {
33public:
34 explicit Dumper(std::string& out) : mOut(out) {}
35
36 void eol() { mOut += '\n'; }
37
Leon Scroggins III823d4ca2023-12-12 16:57:34 -050038 std::string& out() { return mOut; }
39
Dominik Laskowskie70461a2022-08-30 14:42:01 -070040 void dump(std::string_view name, std::string_view value = {}) {
41 using namespace std::string_view_literals;
42
43 for (int i = mIndent; i-- > 0;) mOut += " "sv;
44 mOut += name;
45 if (!name.empty()) mOut += '=';
46 mOut += value;
47 eol();
48 }
49
Dominik Laskowski03cfce82022-11-02 12:13:29 -040050 void dump(std::string_view name, const std::string& value) {
51 dump(name, static_cast<const std::string_view&>(value));
52 }
53
Dominik Laskowskie70461a2022-08-30 14:42:01 -070054 void dump(std::string_view name, bool value) {
55 using namespace std::string_view_literals;
56 dump(name, value ? "true"sv : "false"sv);
57 }
58
59 template <typename T>
Dominik Laskowski03cfce82022-11-02 12:13:29 -040060 void dump(std::string_view name, const std::optional<T>& opt) {
61 if (opt) {
62 dump(name, *opt);
63 } else {
64 using namespace std::string_view_literals;
65 dump(name, "nullopt"sv);
66 }
67 }
68
69 template <typename T>
70 void dump(std::string_view name, const ftl::Optional<T>& opt) {
71 dump(name, static_cast<const std::optional<T>&>(opt));
72 }
73
74 template <typename T, typename... Ts>
75 void dump(std::string_view name, const T& value, const Ts&... rest) {
76 std::string string;
77
78 constexpr bool kIsTuple = sizeof...(Ts) > 0;
79 if constexpr (kIsTuple) {
80 string += '{';
81 }
82
Dominik Laskowskie70461a2022-08-30 14:42:01 -070083 using std::to_string;
Dominik Laskowski03cfce82022-11-02 12:13:29 -040084 string += to_string(value);
85
86 if constexpr (kIsTuple) {
87 string += ((", " + to_string(rest)) + ...);
88 string += '}';
89 }
90
91 dump(name, string);
Dominik Laskowskie70461a2022-08-30 14:42:01 -070092 }
93
94 struct Indent {
95 explicit Indent(Dumper& dumper) : dumper(dumper) { dumper.mIndent++; }
96 ~Indent() { dumper.mIndent--; }
97
98 Dumper& dumper;
99 };
100
Dominik Laskowski5d7de5f2022-11-03 12:38:32 -0400101 struct Section {
102 Section(Dumper& dumper, std::string_view heading) : dumper(dumper) {
103 dumper.dump({}, heading);
104 indent.emplace(dumper);
105 }
106
107 ~Section() {
108 indent.reset();
109 dumper.eol();
110 }
111
112 Dumper& dumper;
113 std::optional<Indent> indent;
114 };
115
Dominik Laskowskie70461a2022-08-30 14:42:01 -0700116private:
117 std::string& mOut;
118 int mIndent = 0;
119};
120
121} // namespace android::utils