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