Documentation
¶
Overview ¶
Package fenneg is a code generation framework for operations log encoding.
Index ¶
- func Chill()
- func ReturnError() *er.RType
- func Run(appName string, handlers *TypesHandlers) error
- func SetStructuredErrorsPkgPath(p string)
- type CustomTypeHandler
- type Go
- type L
- type LoggerType
- type Option
- type Package
- type Project
- type Q
- type Runner
- type RunnerOpLog
- type RunnerOpLogSource
- type RunnerOpLogType
- type TypeHandler
- type TypesHandlers
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Chill ¶ added in v0.4.0
func Chill()
Chill should be called to support int and uint types as int64 and uint64 respectively.
func ReturnError ¶
ReturnError returns a handler to simplify building error messages with structured context in a way that closely replicates the API of github.com/sirkon/errors error processing package.
Example usage:
fenneg.ReturnError().Wrap("err", "$decode").Int("count-$0", 14).Rend(r, countIndex)
The code rendered will look like – countIndex, say, is equal to 25:
return errors.Wrap(err, "decode BranchName.argName(argType)").Int("count-25", 14)
There is a set of predefined values in the code rendering context, besides $decode. Here is the full list (2023-05-15):
- $decode -> "decode $branch.$dst($dstType)"
- $recordTooSmall -> "record buffer is too small"
- $malformedUvarint -> "malformed uvarint sequence"
- $malformedVarint -> "malformed varint sequence"
func Run ¶
func Run( appName string, handlers *TypesHandlers, ) error
Run is the entry point of a final utility.
func SetStructuredErrorsPkgPath ¶
func SetStructuredErrorsPkgPath(p string)
SetStructuredErrorsPkgPath sets custom errors package.
Types ¶
type CustomTypeHandler ¶
type CustomTypeHandler func(handlerPlaceholder, *TypesHandlers) error
CustomTypeHandler custom option type. Cannot be defined outside of this package and only implemented by TypeHandlerByName and NewTypeHandler functions.
func NewTypeHandler ¶
func NewTypeHandler(handler func(p types.Type) TypeHandler) CustomTypeHandler
NewTypeHandler adds custom handler.
func TypeHandlerByName ¶
func TypeHandlerByName(name string, handler func() TypeHandler) CustomTypeHandler
TypeHandlerByName adds this custom handler for the given type.
type L ¶
L does the opposite job to Q for structured values: When you want the builder key to be shown as a variable you use fenneg.L:
fenneg.ReturnError()...Str(fenneg.L("key"), fenneg.Q("value"))...
This will be rendered as
return errors...Str(key, "value")
type LoggerType ¶
LoggerType error logging abstraction to log with text position.
func Logger ¶
func Logger(fset *token.FileSet) LoggerType
Logger returns a standard LoggerType implementation that seems to be sufficient for most needs.
type Option ¶ added in v0.2.0
type Option func(opts *options)
func StructPointer ¶ added in v0.2.0
func StructPointer() Option
func WithDecoderName ¶ added in v0.2.0
func WithEncoderName ¶ added in v0.2.0
func WithFileSuffix ¶ added in v0.2.0
func WithSizeName ¶ added in v0.3.0
type Q ¶
Q is to be used for structured values to be string. Like
orlgen.ReturnError()...Str("key", fenneg.Q("value"))...
To be rendered like
return errors...Str("key", "value")
It will be
return errors...Str("key", value)
Without fenneg.Q
type Runner ¶ added in v0.1.0
type Runner struct {
// contains filtered or unexported fields
}
Runner an entity to do codegen without a final utility.
func NewRunner ¶ added in v0.1.0
func NewRunner(errpkg string, handlers *TypesHandlers) (*Runner, error)
NewRunner constructs an entity to run codegen for specific entities right from the code.
func (*Runner) OpLog ¶ added in v0.1.0
func (r *Runner) OpLog() *RunnerOpLogSource
OpLog run operation log generator.
type RunnerOpLog ¶ added in v0.1.0
type RunnerOpLog struct {
// contains filtered or unexported fields
}
RunnerOpLog oplog codegen runner.
func (*RunnerOpLog) DispatchFunc ¶ added in v0.1.0
func (r *RunnerOpLog) DispatchFunc(name string) *RunnerOpLog
DispatchFunc sets dispatch func name.
func (*RunnerOpLog) DispatchHandler ¶ added in v0.1.0
func (r *RunnerOpLog) DispatchHandler(pkg, typ string) *RunnerOpLog
DispatchHandler sets handler type for the dispatching type.
func (*RunnerOpLog) LengthPrefix ¶ added in v0.1.0
func (r *RunnerOpLog) LengthPrefix(on bool) *RunnerOpLog
LengthPrefix sets generation of a length uleb128 prefix before the rest.
type RunnerOpLogSource ¶ added in v0.1.0
type RunnerOpLogSource struct {
// contains filtered or unexported fields
}
RunnerOpLogSource oplog runner component to set up oplog source interface.
func (*RunnerOpLogSource) Source ¶ added in v0.1.0
func (r *RunnerOpLogSource) Source(pkg, typ string) *RunnerOpLogType
Source set up oplog source interface.
type RunnerOpLogType ¶ added in v0.1.0
type RunnerOpLogType struct {
// contains filtered or unexported fields
}
RunnerOpLogType oplog runner component to set up oplog encoding type.
func (*RunnerOpLogType) Type ¶ added in v0.1.0
func (r *RunnerOpLogType) Type(pkg, typ string) *RunnerOpLog
Type set up oplog encoding type.
type TypeHandler ¶
type TypeHandler interface {
// Name returns a Go type name this handler is for. Meaning
// it will be int8 for int8 handler, etc.
Name(r *Go) string
// Pre renders can be used to render additional stuff at the top
// of the encoding function.
// Take a look at the example:
//
// Let we have a recorder interface
//
// type LogRecorder interface{
// …
// Append(sid types.Index, data []byte) error
// …
// }
//
// This means Append method for an implementation of LogRecorder
// must be generated. And it looks like
//
// func (x *LogRecorderImpl) Append(sid types.Index, data []byte) error {
// {% code generated by Pre calls by handlers of each argument's type %}
// …
// }
//
// A handler can put everything it wants in that area, including
// local variables, additional checks, whatever.
//
// It can be used to store computed lengths for []byte and string
// types handlers for instance. Kinda meaningless for them as
// it len(x) is fast to compute, but some types can be tougher to
// deal with, so this can be pretty useful for them.
Pre(r *Go, src string)
// Len returns a length of buffer required to keep an encoded value.
// It is not possible to have a meaningful value for every type.
// In particular, []byte and string required buffer lentghs are
// only known at the runtime. Implementation MUST return a negative
// value in this case.
Len() int
// LenExpr gives an expression to compute required buffer length
// to encode a type being handled. Must be equal to
// strconv.Itoa(x.Len())
// In case of fixed length, and this is checked.
LenExpr(r *Go, src string) string
// Encoding generates a code that encodes a value of $src into $dst.
// $src and $dst values are also available in the scope of r under
// these exact names, i.e. you can reference them like this:
//
// $dst = binary.LittleEndian.AppendUint32($dst, $src)
//
// And there's $dstType scope variable too containing $dst type.
// The $dst slice is guaranteed to have enough capacity to store
// all encoded data, and it always comes empty, so every encoding
// must follow Append "protocol".
//
// A code is rendered within a context where it (a code generated)
// may return an error. An example of how the end result will look
// like:
//
// func (x *LogRecorderImpl) Append(sid types.Index, data []byte) error {
// dataLen := varsize.Len(data) + len(data)
//
// dst := x.allocateBuffer(4 + 16 + dataLen) // returns empty slice with enough capacity
//
// // Autogenerated data to put Append method code.
// dst = binary.LittleEndian.AppendUint32(dst, uint32(logRecorderCodeAppend))
//
// // Autogenerated code to encode Index type of the sid parameter.
// dst = dst[:len(dst)+16]
// types.IndexEncode(dst, sid)
//
// // Autogenerated code to encode []byte type of the data parameter.
// dst = binary.AppendUvarint(dst, uint64(len(data)))
// dst = append(dst, data...)
//
// if _, err := x.writeBuffer(dst); err != nil {
// return errors.Wrap(err, "write encoded data") // Forcing my errors pkg LMAO.
// }
//
// return nil
// }
//
// It is guaranteed err name is not taken by anything generated - err
// parameter name is prohibited and reserved for its common usage.
// It is not guaranteed 100% though because a user can slap
// something like
// err := "Hello World!"
// in his custom encoding code.
// Take a look at [Auto] handler to see how to deal with err
// within an encoding function scope.
//
// [Auto]: ./internal/handlers/handler_auto.go
Encoding(r *Go, dst, src string)
// Decoding generates a code that decodes a data from $src and stores
// it into $dst.
// - The semantics is exactly the same as for the Encoding, except
// it is $src that is []byte now and $dst is a variable of a
// respective type.
// - It is $srcType instead of the $dstType this time for obvious
// reasons.
// - Same single return value – an error – context for a generated
// code.
//
// Another sort of compliance is needed in this case though:
// - We encode reading data at the head of the $src.
// - When encoding ends we cut amount of bytes we read from the $dst
// to encode. We will cut 4 bytes for encoded int32 value for example.
// - Ulike the Encoding() we may return true or false, in case if we cut
// the head ourselves or want the autogen to make this for us.
// The general advice is to cut manually for a variable length encoding
// and let the autogen do this for the fixed sized ones.
//
// And here is the context similar to one a code generated will work within:
//
// type LogRecorder interface{
// Append(sid Index, data []byte) error
// Delete(sid Index) error
// }
// …
//
// func DispatchLog(h LogHandler, rec []byte) error {
// if len(data) < 4 {
// return errors.New("extract branch code: record buffer is too small")
// }
//
// switch v := logRecorderCode(binary.LittleEndian.Uint32(rec)); v {
// case logRecorderCodeAppend:
// if err := dispatchLogDecodeAppend(h, rec[4:]); err != nil {
// return errors.Wrap(err, "dispatch Append branch")
// }
// case logRecorderCodeDelete:
// if err := dispatchLogDecodeDelete(h, rec[4:]); err != nil {
// return errors.Wrap(err, "dispatch Delete branch")
// }
// default:
// return errors.Newf("unknown branch code %d", v)
// }
// }
//
// func dispatchLogDecodeAppend(h LogHandler, rec []byte) error {
// // decoding code here spawning sid and data variables
//
// var sid Index
// // sid decoding in here
// ...
// if err := h.Append(sid, data); err != nil {
// return errors.New("call Append operation handler").Stg("sid", sid).Int("data-len", len(data))
// }
//
// return nil
// }
//
// Decoding method body has the same err guarantees as for the Encoding,
// that is err is not taken by anything generated by this library handlers.
// Remember, $dst is always declared as
// var $dst $dstType
// Before the code produced by a Decoding call, you just use this variable.
Decoding(r *Go, dst, src string) bool
}
TypeHandler an abstraction for a codegen support of a type.
type TypesHandlers ¶
type TypesHandlers struct {
// contains filtered or unexported fields
}
TypesHandlers this returns type handlers.
func NewTypesHandlers ¶
func NewTypesHandlers(handlers ...CustomTypeHandler) (*TypesHandlers, error)
NewTypesHandlers constructor. User can additional handlers via TypeHandlerByName and NewTypeHandler.
func (*TypesHandlers) Handler ¶
func (h *TypesHandlers) Handler(arg *types.Var) TypeHandler
Handler returns a handler for the given type by its name.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
internal/example
Package example.
|
Package example. |
|
internal
|
|
|
er
Package er provides helpers to simplify building errors returning.
|
Package er provides helpers to simplify building errors returning. |
|
generator
Package generator makes code generation.
|
Package generator makes code generation. |
|
handlers
Package tuples for builtin types.
|
Package tuples for builtin types. |
|
logger
Package logger provides loggers for testing and for the actual job.
|
Package logger provides loggers for testing and for the actual job. |
|
renderer
Package renderer provides a renderer with a custom reporter.
|
Package renderer provides a renderer with a custom reporter. |
|
tdetect
Package tdetect provides types detections means.
|
Package tdetect provides types detections means. |
|
tnmatchers
Package tnmatchers means Type Name MATCHERS.
|
Package tnmatchers means Type Name MATCHERS. |