// Package tdp is td pretty-printing and formatting facilities for types from // MTProto.
package tdp import ( ) // options for formatting. type options struct { writeTypeID bool } // Option of formatting. type Option func(o *options) // WithTypeID adds type id tp type name. func ( *options) { .writeTypeID = true } const ( defaultIdent = " " noIdent = "" ) func ( *strings.Builder, , string, options, reflect.Value) { switch .Kind() { case reflect.Struct, reflect.Ptr, reflect.Interface: , := .Interface().(Object) if { format(, +defaultIdent, , ) } else if .CanAddr() { (, , , , .Addr()) } case reflect.Slice: if , := .Interface().([]byte); { .WriteString(base64.RawURLEncoding.EncodeToString()) return } .WriteRune('\n') for := 0; < .Len(); ++ { := .Index() .WriteString() .WriteString(defaultIdent) .WriteString("- ") (, +defaultIdent, , , ) .WriteRune('\n') } case reflect.Int: // Special case for date. var ( = time.Now() = .AddDate(0, 0, 7).Unix() = .AddDate(-2, 0, 0).Unix() ) := .Int() if > && < && strings.Contains(, "date") { .WriteString(time.Unix(, 0).UTC().Format(time.RFC3339)) } else { .WriteString(strconv.FormatInt(, 10)) } default: .WriteString(fmt.Sprint(.Interface())) } } func ( *strings.Builder, string, options, Object) { if == nil { // No type information is available. it is like Format(nil). .WriteString("<nil>") return } := .TypeInfo() .WriteString(.Name) if .writeTypeID { .WriteRune('#') .WriteString(strconv.FormatInt(int64(.ID), 16)) } if .Null { .WriteString("(nil)") return } := reflect.ValueOf().Elem() for , := range .Fields { if == 0 && .SchemaName == "flags" { // Flag field, skipping. continue } if .Null { // Optional field not set, skipping. continue } .WriteRune('\n') .WriteString() .WriteString(defaultIdent) .WriteString(.SchemaName) .WriteString(": ") formatValue(, , .SchemaName, , .FieldByName(.Name)) } } // Format pretty-prints v into string. func ( Object, ...Option) string { var options for , := range { (&) } var strings.Builder format(&, noIdent, , ) return .String() }