restlicodec

package
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2022 License: BSD-2-Clause Imports: 13 Imported by: 5

Documentation

Index

Constants

View Source
const WildCard = "*"

Variables

View Source
var EmptyReader emptyReader
View Source
var NoopWriter noopWriter
View Source
var (
	NullJSON = errors.New("go-restli: `null` JSON")
)

Functions

func MarshalRestLi

func MarshalRestLi[T any](t T, writer Writer) (err error)

MarshalRestLi calls the corresponding PrimitiveWriter method if T is a Primitive (or an int), and directly calls Marshaler.MarshalRestLi if T is a Marshaler. Otherwise, this function panics.

func ReadArray

func ReadArray[V any](reader Reader, unmarshaler GenericUnmarshaler[V]) (result []V, err error)

func ReadMap

func ReadMap[V any](reader Reader, unmarshaler GenericUnmarshaler[V]) (result map[string]V, err error)

func Ror2PathEscape

func Ror2PathEscape(s string) string

Ror2PathEscape path-escapes the given string using Rest.li's rather opinionated path escaper. The list of unescaped characters was generated directly from the Java code by enumerating all UTF-8 characters and escaping them. Turns out the only differences are that '!' and '*' aren't escaped (while url.PathEscape does) and ':' isn't escaped by url.PathEscape but the Rest.li escaper escapes it.

func Ror2QueryEscape

func Ror2QueryEscape(s string) string

Ror2QueryEscape query-escapes the given string using Rest.li's query escaper (same as Ror2PathEscape). Using the same technique of generating all the UTF8 characters, a handful of characters were found to be escaped differently than how a normal query encoder would do it.

func UnmarshalJSON

func UnmarshalJSON(data []byte, obj Unmarshaler) error

func UnmarshalQueryParamsDecoder

func UnmarshalQueryParamsDecoder[T QueryParamsDecoder[T]](query string) (t T, err error)

func UnmarshalRestLi

func UnmarshalRestLi[T any](reader Reader) (t T, err error)

UnmarshalRestLi calls the corresponding PrimitiveReader method if T is a Primitive (or an int). If T implements Unmarshaler, it is expected to implement PointerUnmarshaler as well and its NewInstance method will be called, then Unmarshaler.UnmarshalRestLi is called on the new pointer. If *T implements Unmarshaler then Unmarshaler.UnmarshalRestLi is called directly on a pointer to a 0-value of T. Otherwise, this function panics.

func ValidateRor2Input added in v1.1.1

func ValidateRor2Input(data string) error

func WriteArray

func WriteArray[T any](writer Writer, array []T, marshaler GenericMarshaler[T]) (err error)

func WriteBool

func WriteBool(v bool, w Writer) error

func WriteBytes

func WriteBytes(v []byte, w Writer) error

func WriteFloat32

func WriteFloat32(v float32, w Writer) error

func WriteFloat64

func WriteFloat64(v float64, w Writer) error

func WriteGenericMap

func WriteGenericMap[K comparable, V any](
	writer Writer,
	entries map[K]V,
	keyMarshaler func(K) (string, error),
	valueMarshaler GenericMarshaler[V],
) (err error)

func WriteInt32

func WriteInt32(v int32, w Writer) error

func WriteInt64

func WriteInt64(v int64, w Writer) error

func WriteMap

func WriteMap[V any](writer Writer, entries map[string]V, marshaler GenericMarshaler[V]) (err error)

func WriteString

func WriteString(v string, w Writer) error

Types

type ArrayReader

type ArrayReader func(reader Reader) (err error)

type ArrayWriter

type ArrayWriter func(itemWriter func() Writer) (err error)

type ComparablePrimitive

type ComparablePrimitive interface {
	int32 | int64 | float32 | float64 | bool | string
}

type DeserializationError

type DeserializationError struct {
	Scope string
	Err   error
}

func (*DeserializationError) Error

func (d *DeserializationError) Error() string

type ExcludedFieldError

type ExcludedFieldError string

func (ExcludedFieldError) Error

func (e ExcludedFieldError) Error() string

type GenericMarshaler

type GenericMarshaler[T any] func(t T, writer Writer) error

type GenericUnmarshaler

type GenericUnmarshaler[T any] func(reader Reader) (T, error)

type InvalidTypeError added in v1.1.1

type InvalidTypeError struct {
	DesiredType, ActualType reflect.Type
	Location                string
}

func (*InvalidTypeError) Error added in v1.1.1

func (c *InvalidTypeError) Error() string

type KeyChecker

type KeyChecker interface {
	IsKeyExcluded(string) bool
}

type MapReader

type MapReader func(reader Reader, field string) (err error)

type MapWriter

type MapWriter func(keyWriter func(key string) Writer) (err error)

type Marshaler

type Marshaler interface {
	MarshalRestLi(Writer) error
}

Marshaler is the interface that should be implemented by objects that can be serialized to JSON and ROR2

type MarshalerFunc

type MarshalerFunc func(Writer) error

The MarshalerFunc type is an adapter to allow the use of ordinary functions as marshalers, useful for inlining marshalers instead of defining new types

func (MarshalerFunc) MarshalRestLi

func (m MarshalerFunc) MarshalRestLi(writer Writer) error

type MissingRequiredFieldsError

type MissingRequiredFieldsError struct {
	Fields []string
}

func (*MissingRequiredFieldsError) Error

type PathSpec

type PathSpec map[string]PathSpec
var NoExcludedFields PathSpec

func NewPathSpec

func NewPathSpec(directives ...string) (p PathSpec)

func (PathSpec) Matches

func (p PathSpec) Matches(path []string) bool

type PointerUnmarshaler

type PointerUnmarshaler[T any] interface {
	Unmarshaler
	NewInstance() T
}

PointerUnmarshaler represents an interface implemented by records and other objects that use pointer receivers for all their methods (unlike enums that use direct receivers).

type Primitive

type Primitive interface {
	ComparablePrimitive | []byte
}

type PrimitiveMarshaler

type PrimitiveMarshaler[T Primitive] func(writer Writer, t T)

type PrimitiveReader

type PrimitiveReader interface {
	ReadInt() (int, error)
	ReadInt32() (int32, error)
	ReadInt64() (int64, error)
	ReadFloat32() (float32, error)
	ReadFloat64() (float64, error)
	ReadBool() (bool, error)
	ReadString() (string, error)
	ReadBytes() ([]byte, error)
}

PrimitiveReader describes the set of functions that read the supported rest.li primitives from the input. Note that if the reader's next input is not a primitive (i.e. it is an object/map or an array), each of these methods will return errors. The encoding spec can be found here: https://linkedin.github.io/rest.li/how_data_is_serialized_for_transport

type PrimitiveWriter

type PrimitiveWriter interface {
	WriteInt(v int)
	WriteInt32(v int32)
	WriteInt64(v int64)
	WriteFloat32(v float32)
	WriteFloat64(v float64)
	WriteBool(v bool)
	WriteString(v string)
	WriteBytes(v []byte)
}

PrimitiveWriter provides the set of functions needed to write the supported rest.li primitives to the backing buffer, according to the rest.li serialization spec: https://linkedin.github.io/rest.li/how_data_is_serialized_for_transport.

type QueryParamsDecoder

type QueryParamsDecoder[T any] interface {
	NewInstance() T
	DecodeQueryParams(reader QueryParamsReader) error
}

type QueryParamsReader

type QueryParamsReader map[string]*ror2QueryReader

func ParseQueryParams

func ParseQueryParams(query string) (QueryParamsReader, error)

func (QueryParamsReader) ReadRecord

func (q QueryParamsReader) ReadRecord(requiredFields RequiredFields, recordReader MapReader) (err error)

type Reader

type Reader interface {
	fmt.Stringer
	PrimitiveReader
	KeyChecker
	// ReadMap tells the Reader that it should expect a map/object as its next input. If it is not (e.g. it is an array
	// or a primitive) it will return an error.
	// Note that not using the inner Reader passed to the MapReader may result in undefined behavior.
	ReadMap(mapReader MapReader) error
	// ReadRecord tells the Reader that it should expect an object as its next input and calls recordReader for each
	// field of the object. If the next input is not an object, it will return an error.
	// Note that not using the inner Reader passed to the MapReader may result in undefined behavior.
	ReadRecord(requiredFields RequiredFields, recordReader MapReader) error
	// ReadArray tells the reader that it should expect an array as its next input. If it is not, it will return an
	// error
	// Note that not using the inner Reader passed to the ArrayReader may result in undefined behavior.
	ReadArray(arrayReader ArrayReader) error
	// ReadInterface reads an interface{} analogous to the 'encoding/json' package. It is a best-effort attempt to
	// deserialize the underlying data into map[string]interface{}, []interface{} or raw primitive types accordingly.
	// Note that for ROR2, because all primitives are encoded as strings, it is impossible to tell what the field's type
	// is intended to be without its schema. Therefore all primitive values are interpreted as strings
	ReadInterface() (interface{}, error)
	// ReadRawBytes returns the next primitive/array/map as a raw, unvalidated byte slice.
	ReadRawBytes() ([]byte, error)

	// Skip skips the next primitive/array/map completely.
	Skip() error
}

func NewInterfaceReader added in v1.1.1

func NewInterfaceReader(v any) Reader

func NewInterfaceReaderWithExcludedFields added in v1.1.1

func NewInterfaceReaderWithExcludedFields(v any, excludedFields PathSpec, leadingScopeToIgnore int) Reader

func NewJsonReader

func NewJsonReader(data []byte) (Reader, error)

func NewJsonReaderWithExcludedFields

func NewJsonReaderWithExcludedFields(data []byte, excludedFields PathSpec, leadingScopeToIgnore int) (Reader, error)

func NewRor2Reader

func NewRor2Reader(data string) (Reader, error)

NewRor2Reader returns a new Reader that reads objects serialized using the rest.li protocol 2.0 object and array representation (ROR2), whose spec is defined here: https://linkedin.github.io/rest.li/spec/protocol#restli-protocol-20-object-and-listarray-representation Because the "reduced" URL encoding used for rest.li headers is a subset of the standard URL encoding, this Reader can be used for both the "full" URL encoding and the "reduced" URL encoding (though query parameters should be read with the reader returned by NewRor2QueryReader as there exist encoding differences, namely " " being encoding as `%20` and `+` respectively) An error will be returned if an upfront validation of the given string reveals it is not a valid ROR2 string. Note that if this function does not return an error, it does _not_ mean subsequent calls to the Read* functions will not return an error

func NewRor2ReaderWithExcludedFields

func NewRor2ReaderWithExcludedFields(data string, excludedField PathSpec, leadingScopeToIgnore int) (Reader, error)

NewRor2ReaderWithExcludedFields is the same as NewRor2Reader excepts it will return an error if it reads a field that is excluded based on the given excluded fields.

type RequiredFields

type RequiredFields []string

type RestLiQueryParamsWriter

type RestLiQueryParamsWriter interface {
	Writer
	WriteParams(paramsWriter MapWriter) error
}

func NewRestLiQueryParamsWriter

func NewRestLiQueryParamsWriter() RestLiQueryParamsWriter

type Ror2PathWriter

type Ror2PathWriter interface {
	Writer
	RawPathSegment(segment string)
}

Ror2PathWriter is an ROR2 Writer that is intended to construct URLs for entities that are ROR2 encoded.

func NewRor2PathWriter

func NewRor2PathWriter() Ror2PathWriter

type Unmarshaler

type Unmarshaler interface {
	UnmarshalRestLi(Reader) error
}

Unmarshaler is the interface that should be implemented by objects that can be deserialized from JSON and ROR2

type UnmarshalerFunc

type UnmarshalerFunc func(Reader) error

The UnmarshalerFunc type is an adapter to allow the use of ordinary functions as unmarshalers, useful for inlining marshalers instead of defining new types

func (UnmarshalerFunc) UnmarshalRestLi

func (u UnmarshalerFunc) UnmarshalRestLi(reader Reader) error

type Writer

type Writer interface {
	PrimitiveWriter
	// WriteRawBytes appends the given bytes to the underlying buffer, without validating the input. Use at your own
	// risk!
	WriteRawBytes([]byte)
	// WriteMap writes the map keys/object fields written by the given lambda between object delimiters. The lambda
	// takes a function that is used to write the key/field name into the object and returns a nested Writer. This
	// Writer should be used to write inner fields. Take the following JSON object:
	//   {
	//     "foo": "bar",
	//     "baz": 42
	//   }
	// This would be written as follows using a Writer:
	//		err := writer.WriteMap(func(keyWriter func(string) restlicodec.Writer) error {
	//			keyWriter("foo").WriteString("bar")
	//			keyWriter("baz").WriteInt32(42)
	//			return nil
	//		}
	// Note that not using the inner Writer returned by the keyWriter may result in undefined behavior.
	WriteMap(mapWriter MapWriter) error
	// WriteArray writes the array items written by the given lambda between array delimiters. The lambda
	// takes a function that is used to signal that a new item is starting and returns a nested Writer. This
	// Writer should be used to write inner fields. Take the following JSON object:
	//   [
	//     "foo",
	//     "bar"
	//   ]
	// This would be written as follows using a Writer:
	//		err := writer.WriteArray(func(itemWriter func() restlicodec.Writer) error {
	//			itemWriter().WriteString("foo")
	//			itemWriter().WriteString("bar")
	//			return nil
	//		}
	// Note that not using the inner Writer returned by the itemWriter may result in undefined behavior.
	WriteArray(arrayWriter ArrayWriter) error
	// IsKeyExcluded checks whether or not the given key or field name at the current scope should be included in
	// serialization. Exclusion behavior is already built into the writer but this is intended for Marhsalers that use
	// custom serialization logic on top of the Writer
	IsKeyExcluded(key string) bool
	// SetScope returns a copy of the current writer with the given scope. For internal use only by Marshalers that use
	// custom serialization logic on top of the Writer. Designed to work around the backing PathSpec for field
	// exclusion.
	SetScope(...string) Writer
	// Finalize returns the created object as a string and releases the pooled underlying buffer. Subsequent calls will
	// return the empty string
	Finalize() string
}

Writer is the interface implemented by all serialization mechanisms supported by rest.li. See the New*Writer functions provided in package for all the supported serialization mechanisms.

func NewCompactJsonWriter

func NewCompactJsonWriter() Writer

NewCompactJsonWriter returns a Writer that serializes objects using JSON. This representation has no extraneous whitespace and is intended for wire transport.

func NewCompactJsonWriterWithExcludedFields

func NewCompactJsonWriterWithExcludedFields(excludedFields PathSpec) Writer

NewCompactJsonWriterWithExcludedFields returns a Writer that serializes objects using JSON, excluding any fields matched by the given PathSpec. This representation has no extraneous whitespace and is intended for wire transport.

func NewPrettyJsonWriter

func NewPrettyJsonWriter() Writer

NewPrettyJsonWriter returns a Writer that serializes objects using JSON. This representation delimits fields and array items using newlines and provides indentation for nested objects. It generates a lot of unnecessary bytes and is intended primarily for debugging or human-readability purposes.

func NewPrettyJsonWriterWithExcludedFields

func NewPrettyJsonWriterWithExcludedFields(excludedFields PathSpec) Writer

NewPrettyJsonWriterWithExcludedFields returns a Writer that serializes objects using JSON, excluding any fields matched by the given PathSpec. This representation delimits fields and array items using newlines and provides indentation for nested objects. It generates a lot of unnecessary bytes and is intended primarily for debugging or human-readability purposes.

func NewRor2HeaderWriter

func NewRor2HeaderWriter() Writer

NewRor2HeaderWriter returns a new Writer that serializes objects using the rest.li protocol 2.0 object and array representation (ROR2), whose spec is defined here: https://linkedin.github.io/rest.li/spec/protocol#restli-protocol-20-object-and-listarray-representation This specific Writer uses the "reduced" URL encoding instead of the full URL encoding, i.e. it only escapes the following characters using url.QueryEscape:

% , ( ) ' :

func NewRor2HeaderWriterWithExcludedFields

func NewRor2HeaderWriterWithExcludedFields(excludedFields PathSpec) Writer

NewRor2HeaderWriterWithExcludedFields returns a new Writer that serializes objects using the rest.li protocol 2.0 object and array representation (ROR2), whose spec is defined here: https://linkedin.github.io/rest.li/spec/protocol#restli-protocol-20-object-and-listarray-representation This specific Writer uses the "reduced" URL encoding instead of the full URL encoding, i.e. it only escapes the following characters using url.QueryEscape:

% , ( ) ' :

Any fields matched by the given PathSpec are excluded from serialization

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL