github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/internal/pretty/pretty.go (about)

     1  /*
     2   *
     3   * Copyright 2021 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  // Package pretty defines helper functions to pretty-print structs for logging.
    20  package pretty
    21  
    22  import (
    23  	"bytes"
    24  	"encoding/json"
    25  	"fmt"
    26  
    27  	"github.com/golang/protobuf/jsonpb"
    28  	protov1 "github.com/golang/protobuf/proto"
    29  	"google.golang.org/protobuf/encoding/protojson"
    30  	protov2 "google.golang.org/protobuf/proto"
    31  )
    32  
    33  const jsonIndent = "  "
    34  
    35  // ToJSON marshals the input into a json string.
    36  //
    37  // If marshal fails, it falls back to fmt.Sprintf("%+v").
    38  func ToJSON(e interface{}) string {
    39  	switch ee := e.(type) {
    40  	case protov1.Message:
    41  		mm := jsonpb.Marshaler{Indent: jsonIndent}
    42  		ret, err := mm.MarshalToString(ee)
    43  		if err != nil {
    44  			// This may fail for proto.Anys, e.g. for xDS v2, LDS, the v2
    45  			// messages are not imported, and this will fail because the message
    46  			// is not found.
    47  			return fmt.Sprintf("%+v", ee)
    48  		}
    49  		return ret
    50  	case protov2.Message:
    51  		mm := protojson.MarshalOptions{
    52  			Multiline: true,
    53  			Indent:    jsonIndent,
    54  		}
    55  		ret, err := mm.Marshal(ee)
    56  		if err != nil {
    57  			// This may fail for proto.Anys, e.g. for xDS v2, LDS, the v2
    58  			// messages are not imported, and this will fail because the message
    59  			// is not found.
    60  			return fmt.Sprintf("%+v", ee)
    61  		}
    62  		return string(ret)
    63  	default:
    64  		ret, err := json.MarshalIndent(ee, "", jsonIndent)
    65  		if err != nil {
    66  			return fmt.Sprintf("%+v", ee)
    67  		}
    68  		return string(ret)
    69  	}
    70  }
    71  
    72  // FormatJSON formats the input json bytes with indentation.
    73  //
    74  // If Indent fails, it returns the unchanged input as string.
    75  func FormatJSON(b []byte) string {
    76  	var out bytes.Buffer
    77  	err := json.Indent(&out, b, "", jsonIndent)
    78  	if err != nil {
    79  		return string(b)
    80  	}
    81  	return out.String()
    82  }