document

package
v1.7.0 Latest Latest
Warning

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

Go to latest
Published: Sep 17, 2025 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Create a document in the whitespace separated format.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrFieldIndexedNotFound         = errors.New("field does not exist")
	ErrStartedToWrite               = errors.New("document started to write, need to reset document to edit")
	ErrInvalidPaddingRune           = errors.New("only whitespace characters can be used for padding")
	ErrOmitHeaders                  = errors.New("document configured to omit headers")
	ErrLineNotFound                 = errors.New("line does not exist")
	ErrFieldCount                   = errors.New("wrong number of fields")
	ErrCannotSortNonTabularDocument = errors.New("the document is non-tabular and cannot be sorted")
	ErrFieldNotFoundForSortBy       = errors.New("the field was not found")
)
View Source
var (
	ErrNotEnoughLines    = errors.New("document does not have more than 1 line")
	ErrFieldNameNotFound = errors.New("field not found")
)
View Source
var (
	ErrUnsupportMarshalType = errors.New("unsupported type to marshal")
	ErrNoDataMarshalled     = errors.New("no data marshalled")
)

Functions

func Field

func Field(val string) appendLineField

func Fields

func Fields(s ...string) []appendLineField

func Marshal added in v1.7.0

func Marshal[T any](s []T) ([]byte, error)

Marshal returns a WSV encoding of s.

Marsal iterates over the elements of s. For each element of s it iterates over the fields of in the s[n].

If a field in the s[n] implements MarshalWSV it will call the [MarshalWSV.MarshalWSV()]. Otherwise it will use the default implementation.

Marshal uses the `wsv` tag of fields within s[n] in following format: `wsv:"[field name][,format:[[string]][,comment]"`

`field name` attribute can be empty and will take the name of the exported field.

`format:` uses the value immediately after the colon `:`, until the end of the tag or a comma `,` unless enclosed in single quotes `'`.

Struct tags with the `comment` attribute will be appended to the end of the line as comment. Subsequent fields with the `comment` attribute will be appended to previous comment on the same line in the order declared in the struct with a single space ` ` between each field. Empty or nil values will not be appended. The `field name` is ignored but must contain a comma `,` before.

Example:

type User struct {
  LastLogin time.Time `wsv:",comment"`
  Points float64 `wsv:",format:%.4f,comment"`
}

Values will parsed with their formats or call [MarshalWSV.MarshalWSV()] prior to appending comments. See below for details about the `format`

All exported fields in the struct s[n] will try to marshal unless a specific `wsv` tag with a field name of `-` is provided. If the field name name is expect to literally be `-` there needs to be comma `,` to follow.

Supports `string`, `int`, `bool`, `float`, `time.Time`.

Fields with the type of `string` do not support the `format:` attribute in the struct tag and will just be ignored if specified.

Fields with the type of `int` can alter their byte representation with the `format:` attribute in the struct tag. The format is in the format of `fmt.Sprintf` and the default is `%d`.

Example:

type Person struct {
   Age int `wsv:"age,format:%d"`
}

Fields with type `bool` can also alter their byte representation with the `format:` attribute in the struct tag. The format is template `true|false` with the left side of the `|` representing the literal value of `true` and the right side representing the literal value of `false`. The default is `True|False`.

Example:

type User struct {
  IsAdmin bool `wsv:"Admin,format:yes|no"`
}

Field with type `float` can alter their byte representation with the `format:` attribute in the struct tag. The format is in the format of `fmt.Sprintf` and the default is `%.2f`

type Employee struct {
  Salary float32 `wsv:"Weekly Salary,format:%.2f"`
}

Field with type `time.Time` can alter their byte representation with the `format:` attribute in the struct tag. The format is in the format of `time.Format` and the default is `time.RFC3339` The time can be written a literal string layout `2006-01-02` or using a the following shorthand values:

* layout

* ansic

* unixdate

* rubydate

* rfc822

* rfc822z

* rfc850

* rfc1123

* rfc1123z

* rfc3339

* rfc3339nano

* kitchen

* stamp

* stampmilli

* stampmicro

* stampnano

* datetime

* dateonly

* date

* timeonly

* time

If you need a format with `,` you can escape the `,` by wrapping the `format` in `'` single qoutes. For example `wsv:"field,format:'Jan 02, 2006'`.

Example:

type TimeOff struct {
  Date *time.Time `wsv:"PTO,format:'January 02, 2006'"`
  Requested time.Time `wsv:"Requested,format:2006-01-02"`
  Approved *time.Time `wsv:,format:rfc3339"`
}

func MarshalWithOptions added in v1.7.0

func MarshalWithOptions[T any](s []T, options ...*internal.SortOption) ([]byte, error)

Marshal returns a WSV encoding of s with the option to sort by columns.

Marsal iterates over the elements of s. For each element of s it iterates over the fields of in the s[n].

If a field in the s[n] implements MarshalWSV it will call the [MarshalWSV.MarshalWSV()]. Otherwise it will use the default implementation.

Marshal uses the `wsv` tag of fields within s[n] in following format: `wsv:"[field name][,format:[[string]][,comment]"`

`field name` attribute can be empty and will take the name of the exported field.

`format:` uses the value immediately after the colon `:`, until the end of the tag or a comma `,` unless enclosed in single quotes `'`.

Struct tags with the `comment` attribute will be appended to the end of the line as comment. Subsequent fields with the `comment` attribute will be appended to previous comment on the same line in the order declared in the struct with a single space ` ` between each field. Empty or nil values will not be appended. The `field name` is ignored but must contain a comma `,` before.

Example:

type User struct {
  LastLogin time.Time `wsv:",comment"`
  Points float64 `wsv:",format:%.4f,comment"`
}

Values will parsed with their formats or call [MarshalWSV.MarshalWSV()] prior to appending comments. See below for details about the `format`

All exported fields in the struct s[n] will try to marshal unless a specific `wsv` tag with a field name of `-` is provided. If the field name name is expect to literally be `-` there needs to be comma `,` to follow.

Supports `string`, `int`, `bool`, `float`, `time.Time`.

Fields with the type of `string` do not support the `format:` attribute in the struct tag and will just be ignored if specified.

Fields with the type of `int` can alter their byte representation with the `format:` attribute in the struct tag. The format is in the format of `fmt.Sprintf` and the default is `%d`.

Example:

type Person struct {
   Age int `wsv:"age,format:%d"`
}

Fields with type `bool` can also alter their byte representation with the `format:` attribute in the struct tag. The format is template `true|false` with the left side of the `|` representing the literal value of `true` and the right side representing the literal value of `false`. The default is `True|False`.

Example:

type User struct {
  IsAdmin bool `wsv:"Admin,format:yes|no"`
}

Field with type `float` can alter their byte representation with the `format:` attribute in the struct tag. The format is in the format of `fmt.Sprintf` and the default is `%.2f`

type Employee struct {
  Salary float32 `wsv:"Weekly Salary,format:%.2f"`
}

Field with type `time.Time` can alter their byte representation with the `format:` attribute in the struct tag. The format is in the format of `time.Format` and the default is `time.RFC3339` The time can be written a literal string layout `2006-01-02` or using a the following shorthand values:

* layout

* ansic

* unixdate

* rubydate

* rfc822

* rfc822z

* rfc850

* rfc1123

* rfc1123z

* rfc3339

* rfc3339nano

* kitchen

* stamp

* stampmilli

* stampmicro

* stampnano

* datetime

* dateonly

* date

* timeonly

* time

If you need a format with `,` you can escape the `,` by wrapping the `format` in `'` single qoutes. For example `wsv:"field,format:'Jan 02, 2006'`.

Example:

type TimeOff struct {
  Date *time.Time `wsv:"PTO,format:'January 02, 2006'"`
  Requested time.Time `wsv:"Requested,format:2006-01-02"`
  Approved *time.Time `wsv:,format:rfc3339"`
}

func Null

func Null() appendLineField

func Sort

func Sort(fieldName string) *internal.SortOption

func SortDesc

func SortDesc(fieldName string) *internal.SortOption

func SortDuration added in v1.7.0

func SortDuration(fieldName string) *internal.SortOption

func SortDurationDesc added in v1.7.0

func SortDurationDesc(fieldName string) *internal.SortOption

func SortNumber

func SortNumber(fieldName string) *internal.SortOption

func SortNumberBase

func SortNumberBase(fieldName string, base int) *internal.SortOption

func SortNumberBaseDesc

func SortNumberBaseDesc(fieldName string, base int) *internal.SortOption

func SortNumberDesc

func SortNumberDesc(fieldName string) *internal.SortOption

func SortTime

func SortTime(fieldName string, format string) *internal.SortOption

func SortTimeDesc

func SortTimeDesc(fieldName string, format string) *internal.SortOption

Types

type Document

type Document struct {
	Tabular     bool
	EmitHeaders bool
	// contains filtered or unexported fields
}

func NewDocument

func NewDocument() *Document

func (*Document) AddLine

func (doc *Document) AddLine() (Line, error)

func (*Document) AppendHeader

func (doc *Document) AppendHeader(val string)

func (*Document) AppendLine

func (doc *Document) AppendLine(fields ...appendLineField) (Line, error)

func (*Document) AppendValues

func (doc *Document) AppendValues(vals ...string) (Line, error)

Adds a line to a document and then appends values to the line added

the literally "-" will be interpreded as null, if you need a literal "-" use the `line.Append(val string)` function

returns the line that was added, can return an error due validation errors

func (*Document) CalculateMaxFieldLengths

func (doc *Document) CalculateMaxFieldLengths()

func (*Document) CommentFor

func (doc *Document) CommentFor(ln int) (string, error)

Returns a comment if one exists for the rows or an error if comment does not exist lines are 1-indexed

func (*Document) HasHeaders

func (doc *Document) HasHeaders() bool

func (*Document) Headers

func (doc *Document) Headers() []string

func (*Document) Line

func (doc *Document) Line(ln int) (Line, error)

Returns the document at the ln specified. Lines are 1-index. If the line does not exist there is an ErrLineNotFound error

func (*Document) LineCount

func (doc *Document) LineCount() int

func (*Document) Lines

func (d *Document) Lines() []Line

func (*Document) MaxColumnWidth

func (doc *Document) MaxColumnWidth(col int) (int, error)

func (*Document) ReIndexLineNumbers

func (doc *Document) ReIndexLineNumbers()

func (*Document) ResetWrite

func (doc *Document) ResetWrite()

func (*Document) SetHideHeaderStyle

func (doc *Document) SetHideHeaderStyle(v bool)

func (*Document) SetMaxColumnWidth

func (doc *Document) SetMaxColumnWidth(col int, len int)

func (*Document) SetPadding

func (doc *Document) SetPadding(rs []rune) error

func (*Document) SortBy

func (doc *Document) SortBy(sortOptions ...*internal.SortOption) error

Sorts the documents lines in place based on the sort options

Will sort until finished or a field specified is not found, in which case a ErrFieldNotFoundForSortBy is returned

func (*Document) UpdateHeader

func (doc *Document) UpdateHeader(fi int, val string) error

func (*Document) Write

func (doc *Document) Write() ([]byte, error)

Write, writes the currently line to a slice of bytes based on the current line in process, calling write will increment the counter after each successful call. Once all lines are process will return will return empty slice, EOF

func (*Document) WriteAll

func (doc *Document) WriteAll() ([]byte, error)

func (*Document) WriteAllTo

func (doc *Document) WriteAllTo(w io.Writer) error

func (*Document) WriteLine

func (doc *Document) WriteLine(n int, includeHeader bool) ([]byte, error)

type Line added in v1.1.0

type Line interface {
	// determine if tabular document line is valid based on the number of lines of the first row/header, returns true, nil if has the correct number of data fields
	//
	// returns false, and an error documenting the difference
	Validate() (bool, error)
	// Append a value to the end of the line
	Append(val string) error
	// Append multiple values at once
	AppendValues(val ...string) error
	// Append a null value to the end of the line
	AppendNull() error
	// Get the next field value, or error if at the end of the line for data
	NextField() (*internal.Field, error)
	// Record at index, or Field Not found, field 0-indexed
	Field(fieldIndex int) (*internal.Field, error)
	// A count of the number of data fields in the line
	FieldCount() int
	// Get the line number
	LineNumber() int
	// Update the value of a particular field
	UpdateField(fieldIndex int, val string) error
	// Update a comment on the line
	UpdateComment(val string)
	// Get the value of comment for the line
	Comment() string
	// Update the field name for the field at the given index
	//
	// ErrFieldNotFound is returned if there is no field at the
	UpdateFieldName(fieldIndex int, val string) error

	// Select a field record by name
	FieldByName(fieldName string) (*internal.Field, error)

	// fields from the line
	Fields() []internal.Field
	// returns true if this line is a header line
	IsHeader() bool
	// re-indexes line numbers back on order in the line slices
	ReIndexLineNumber(i int)
}

type MarshalWSV added in v1.7.0

type MarshalWSV interface {
	MarshalWSV(format string) (*string, error)
}

type SortFunc

type SortFunc = func(prv *internal.Field, curr *internal.Field) bool

evaluates previous and current record fields and should return true if current field is after previous field

type WriteError

type WriteError struct {
	// contains filtered or unexported fields
}

func (*WriteError) Error

func (e *WriteError) Error() string

Jump to

Keyboard shortcuts

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