tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

structured.h (5426B)


      1 // Copyright 2022 The Abseil Authors.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      https://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 //
     15 // -----------------------------------------------------------------------------
     16 // File: log/internal/structured.h
     17 // -----------------------------------------------------------------------------
     18 
     19 #ifndef ABSL_LOG_INTERNAL_STRUCTURED_H_
     20 #define ABSL_LOG_INTERNAL_STRUCTURED_H_
     21 
     22 #include <ostream>
     23 #include <string>
     24 
     25 #include "absl/base/attributes.h"
     26 #include "absl/base/config.h"
     27 #include "absl/functional/any_invocable.h"
     28 #include "absl/log/internal/log_message.h"
     29 #include "absl/log/internal/structured_proto.h"
     30 #include "absl/strings/str_cat.h"
     31 #include "absl/strings/string_view.h"
     32 
     33 namespace absl {
     34 ABSL_NAMESPACE_BEGIN
     35 namespace log_internal {
     36 
     37 class [[nodiscard]] AsLiteralImpl final {
     38 public:
     39  explicit AsLiteralImpl(absl::string_view str ABSL_ATTRIBUTE_LIFETIME_BOUND)
     40      : str_(str) {}
     41  AsLiteralImpl(const AsLiteralImpl&) = default;
     42  AsLiteralImpl& operator=(const AsLiteralImpl&) = default;
     43 
     44 private:
     45  absl::string_view str_;
     46 
     47  friend std::ostream& operator<<(std::ostream& os,
     48                                  AsLiteralImpl&& as_literal) {
     49    return os << as_literal.str_;
     50  }
     51  void AddToMessage(log_internal::LogMessage& m) {
     52    m.CopyToEncodedBuffer<log_internal::LogMessage::StringType::kLiteral>(str_);
     53  }
     54  friend log_internal::LogMessage& operator<<(log_internal::LogMessage& m,
     55                                              AsLiteralImpl as_literal) {
     56    as_literal.AddToMessage(m);
     57    return m;
     58  }
     59 };
     60 
     61 enum class StructuredStringType {
     62  kLiteral,
     63  kNotLiteral,
     64 };
     65 
     66 // Structured log data for a string and associated structured proto field,
     67 // both of which must outlive this object.
     68 template <StructuredStringType str_type>
     69 class [[nodiscard]] AsStructuredStringTypeImpl final {
     70 public:
     71  constexpr AsStructuredStringTypeImpl(
     72      absl::string_view str ABSL_ATTRIBUTE_LIFETIME_BOUND,
     73      StructuredProtoField field ABSL_ATTRIBUTE_LIFETIME_BOUND)
     74      : str_(str), field_(field) {}
     75 
     76 private:
     77  absl::string_view str_;
     78  StructuredProtoField field_;
     79 
     80  friend std::ostream& operator<<(std::ostream& os,
     81                                  const AsStructuredStringTypeImpl& impl) {
     82    return os << impl.str_;
     83  }
     84  void AddToMessage(LogMessage& m) const {
     85    if (str_type == StructuredStringType::kLiteral) {
     86      return m.CopyToEncodedBufferWithStructuredProtoField<
     87          log_internal::LogMessage::StringType::kLiteral>(field_, str_);
     88    } else {
     89      return m.CopyToEncodedBufferWithStructuredProtoField<
     90          log_internal::LogMessage::StringType::kNotLiteral>(field_, str_);
     91    }
     92  }
     93  friend LogMessage& operator<<(LogMessage& m,
     94                                const AsStructuredStringTypeImpl& impl) {
     95    impl.AddToMessage(m);
     96    return m;
     97  }
     98 };
     99 
    100 using AsStructuredLiteralImpl =
    101    AsStructuredStringTypeImpl<StructuredStringType::kLiteral>;
    102 using AsStructuredNotLiteralImpl =
    103    AsStructuredStringTypeImpl<StructuredStringType::kNotLiteral>;
    104 
    105 // Structured log data for a stringifyable type T and associated structured
    106 // proto field, both of which must outlive this object.
    107 template <typename T>
    108 class [[nodiscard]] AsStructuredValueImpl final {
    109 public:
    110  using ValueFormatter = absl::AnyInvocable<std::string(T) const>;
    111 
    112  constexpr AsStructuredValueImpl(
    113      T value ABSL_ATTRIBUTE_LIFETIME_BOUND,
    114      StructuredProtoField field ABSL_ATTRIBUTE_LIFETIME_BOUND,
    115      ValueFormatter value_formatter =
    116          [](T value) { return absl::StrCat(value); })
    117      : value_(value),
    118        field_(field),
    119        value_formatter_(std::move(value_formatter)) {}
    120 
    121 private:
    122  T value_;
    123  StructuredProtoField field_;
    124  ValueFormatter value_formatter_;
    125 
    126  friend std::ostream& operator<<(std::ostream& os,
    127                                  const AsStructuredValueImpl& impl) {
    128    return os << impl.value_formatter_(impl.value_);
    129  }
    130  void AddToMessage(LogMessage& m) const {
    131    m.CopyToEncodedBufferWithStructuredProtoField<
    132        log_internal::LogMessage::StringType::kNotLiteral>(
    133        field_, value_formatter_(value_));
    134  }
    135  friend LogMessage& operator<<(LogMessage& m,
    136                                const AsStructuredValueImpl& impl) {
    137    impl.AddToMessage(m);
    138    return m;
    139  }
    140 };
    141 
    142 // Template deduction guide so `AsStructuredValueImpl(42, data)` works
    143 // without specifying the template type.
    144 template <typename T>
    145 AsStructuredValueImpl(T value, StructuredProtoField field)
    146    -> AsStructuredValueImpl<T>;
    147 
    148 // Template deduction guide so `AsStructuredValueImpl(42, data, formatter)`
    149 // works without specifying the template type.
    150 template <typename T>
    151 AsStructuredValueImpl(
    152    T value, StructuredProtoField field,
    153    typename AsStructuredValueImpl<T>::ValueFormatter value_formatter)
    154    -> AsStructuredValueImpl<T>;
    155 
    156 }  // namespace log_internal
    157 ABSL_NAMESPACE_END
    158 }  // namespace absl
    159 
    160 #endif  // ABSL_LOG_INTERNAL_STRUCTURED_H_