blob: ee942177e57ba085ef604ad41f33ca65b0a460d8 [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
38 void dump(std::string_view name, std::string_view value = {}) {
39 using namespace std::string_view_literals;
40
41 for (int i = mIndent; i-- > 0;) mOut += " "sv;
42 mOut += name;
43 if (!name.empty()) mOut += '=';
44 mOut += value;
45 eol();
46 }
47
Dominik Laskowski03cfce82022-11-02 12:13:29 -040048 void dump(std::string_view name, const std::string& value) {
49 dump(name, static_cast<const std::string_view&>(value));
50 }
51
Dominik Laskowskie70461a2022-08-30 14:42:01 -070052 void dump(std::string_view name, bool value) {
53 using namespace std::string_view_literals;
54 dump(name, value ? "true"sv : "false"sv);
55 }
56
57 template <typename T>
Dominik Laskowski03cfce82022-11-02 12:13:29 -040058 void dump(std::string_view name, const std::optional<T>& opt) {
59 if (opt) {
60 dump(name, *opt);
61 } else {
62 using namespace std::string_view_literals;
63 dump(name, "nullopt"sv);
64 }
65 }
66
67 template <typename T>
68 void dump(std::string_view name, const ftl::Optional<T>& opt) {
69 dump(name, static_cast<const std::optional<T>&>(opt));
70 }
71
72 template <typename T, typename... Ts>
73 void dump(std::string_view name, const T& value, const Ts&... rest) {
74 std::string string;
75
76 constexpr bool kIsTuple = sizeof...(Ts) > 0;
77 if constexpr (kIsTuple) {
78 string += '{';
79 }
80
Dominik Laskowskie70461a2022-08-30 14:42:01 -070081 using std::to_string;
Dominik Laskowski03cfce82022-11-02 12:13:29 -040082 string += to_string(value);
83
84 if constexpr (kIsTuple) {
85 string += ((", " + to_string(rest)) + ...);
86 string += '}';
87 }
88
89 dump(name, string);
Dominik Laskowskie70461a2022-08-30 14:42:01 -070090 }
91
92 struct Indent {
93 explicit Indent(Dumper& dumper) : dumper(dumper) { dumper.mIndent++; }
94 ~Indent() { dumper.mIndent--; }
95
96 Dumper& dumper;
97 };
98
Dominik Laskowski5d7de5f2022-11-03 12:38:32 -040099 struct Section {
100 Section(Dumper& dumper, std::string_view heading) : dumper(dumper) {
101 dumper.dump({}, heading);
102 indent.emplace(dumper);
103 }
104
105 ~Section() {
106 indent.reset();
107 dumper.eol();
108 }
109
110 Dumper& dumper;
111 std::optional<Indent> indent;
112 };
113
Dominik Laskowskie70461a2022-08-30 14:42:01 -0700114private:
115 std::string& mOut;
116 int mIndent = 0;
117};
118
119} // namespace android::utils