The Gophercraft text format is used in Gophercraft for configuration and data interchange.
You can think about it as a more lightweight JSON, but with some extra bells and whistles.
Another difference from JSON is that it cannot be used to represent arbitrary structures. Data must be serialized according to Go types.
type Document struct {
StringField string
IntegerSlice []int
Map map[string]string
}
{
/*
*
*
* Block comments
*
*/
// Or double-slash comments are allowed
// Quotes are not required for words if they contain no whitespace or reserved characters
StringField QuotesUnnecessary
// Keys and values are both words. All words may be quoted.
"IntegerSlice"
{
1
2
3
"4" // Not a string, but can be quoted.
}
Map
{
"Key" value
other_key "another value"
}
}
Encoded values can also be expressed in a tabular form (unkeyed structs).
This can be desirable when working with database files that are extremely large and contain many records, as it reduces the redudancy of repeating struct keys.
// Table header
[ StringField IntegerSlice Map ]
// Empty row
{ "" {} {} }
// Non-empty row
{ "string value" { 1 2 3 4 } { key value otherkey othervalue } }
Easy functions for dealing with a single record:
bytes, err := text.Marshal(&record)
err = text.Unmarshal(bytes, &record)
Use Encoder and Decoder to deal with many records in one stream, or make use of custom options:
encoder := text.NewEncoder(file)
// When using standard notation
encoder.Indent = "\t"
// When using tabular notation, this is what is placed between columns
encoder.Indent = " "
// Set tabular to true if you wish to encode
// table files with a much smaller size (See: Tabular documents)
encoder.Tabular = true|false
for _, record := range records {
err = encoder.Encode(&record)
// ...
}
decoder := text.NewDecoder(file)
for {
err = decoder.Decode(&record)
if errors.Is(err, io.EOF) {
// done reading
break
} else if err != nil {
// deal with error
break
}
// handle decoded record
}
// close fd
file.Close()