// Package encode provides value encoders for [go.pact.im/x/phcformat] package.
package encode import ( ) // Appender represents an encodable value that uses append-style API. type Appender interface { // Append appends the encoded value to the dst and returns the resulting // slice. Append(dst []byte) []byte } // Nil returns a nil Appender option. func () option.Of[Appender] { return option.Nil[Appender]() } // StringOrBytes is a union of string and byte slice types. type StringOrBytes interface { ~string | ~[]byte } // Empty is an Appender that does nothing. type Empty struct{} // NewEmpty returns a new Empty instance. func () Empty { return Empty{} } // Append implements the Appender interface. func ( Empty) ( []byte) []byte { return } // Option is an Appender that appends optional value if it is set. type Option[ Appender] struct { Option option.Of[] } // NewOption returns a new Option instance. func [ Appender]( option.Of[]) Option[] { return Option[]{ Option: , } } // Append implements the Appender interface. func ( Option[]) ( []byte) []byte { , := .Option.Unwrap() if ! { return } return .Append() } // Concat is an Appender that concatenates two values. type Concat[, Appender] struct { // A is the first value to append. A // B is the second value to append. B } // NewConcat returns a new Concat instance. func [, Appender]( , ) Concat[, ] { return Concat[, ]{ A: , B: , } } // Append implements the Appender interface. func ( Concat[, ]) ( []byte) []byte { = .A.Append() = .B.Append() return } // List is an Appender that appends a list of values separated with the given // separator. type List[, Appender] struct { // Separator is a separator that is appended between elements. Separator // Elements is a list of elements to append. Elements [] } // NewList returns a new List instance. func [, Appender]( , ...) List[, ] { return List[, ]{ Separator: , Elements: , } } // Append implements the Appender interface. func ( List[, ]) ( []byte) []byte { if len(.Elements) == 0 { return } = .Elements[0].Append() for , := range .Elements[1:] { = .Separator.Append() = .Append() } return } // KV is an Appender that appends a key-value pair separated with the given // separator. type KV[, , Appender] struct { // Key is the key in the key-value pair. Key // Sep is a separator that is appended between key and value. Sep // Val is the value in the key-value pair. Val } // NewKV returns a new KV instance. func [, , Appender]( , , ) KV[, , ] { return KV[, , ]{ Key: , Sep: , Val: , } } // Append implements the Appender interface. func ( KV[, , ]) ( []byte) []byte { = .Key.Append() = .Sep.Append() = .Val.Append() return } // Byte is an Appender that appends a single byte. type Byte byte // NewByte returns a new Byte instance. func ( byte) Byte { return Byte() } // Append implements the Appender interface. func ( Byte) ( []byte) []byte { return append(, byte()) } // String is an Appender that appends string. type String string // NewString returns a new String instance. func ( string) String { return String() } // Append implements the Appender interface. func ( String) ( []byte) []byte { return append(, ...) } // Bytes is an Appender that appends byte slice. type Bytes []byte // NewBytes returns a new Bytes instance. func ( []byte) Bytes { return Bytes() } // Append implements the Appender interface. func ( Bytes) ( []byte) []byte { return append(, ...) } // Uint is an Appender that encodes uint as a decimal number. type Uint uint // NewUint returns a new Uint instance. func ( uint) Uint { return Uint() } // Append implements the Appender interface. func ( Uint) ( []byte) []byte { return strconv.AppendUint(, uint64(), 10) } // Base64 is an Appender that encodes string or byte slice using // base64.RawStdEncoding. type Base64[ StringOrBytes] struct { // Data is the unencoded data. Data } // NewBase64 returns a new Base64 instance. func [ StringOrBytes]( ) Base64[] { return Base64[]{ Data: , } } // Append implements the Appender interface. func ( Base64[]) ( []byte) []byte { return base64Append(base64.RawStdEncoding, , []byte(.Data)) } // base64Append is an append-style function for base64 encoding. // // See also https://go.dev/issue/19366 func ( *base64.Encoding, , []byte) []byte { := len() := .EncodedLen(len()) if cap()- < { = append(, make([]byte, )...) } else { = [:+] } .Encode([:], ) return }