This document is a systematic reference for every exported identifier in the
jsonstat-go module (module github.com/jsonstat/go). It is generated
from the package godoc and kept in sync with the source; when in doubt, run
go doc for the authoritative wording.
Notation: signatures are written as in Go. A trailing
// →introduces the concrete Go type returned by the function. Click any symbol to jump to its definition.
- Status
- Package
jsonstat - Package
jsonstathttp - Package
internal/stride - CLI (
cmd/jsonstat) - Worked examples
The current release is v0.1.1. The compiled-in
Version reads "0.1.1" and is overridable at link time;
release builds inject the exact tag from VCS via
-ldflags (see Version and
Makefile):
make install-cli # uses `git describe --tags --always --dirty`
make install-cli VERSION=v0.1.1 # explicit override
go build -ldflags '-X github.com/jsonstat/go.Version=v0.1.1' ./cmd/jsonstatjsonstat-go targets JSON-stat 2.0 (FormatVersion),
matching the modern ecosystem (toolkit, php, io, validator, wasm). Pre-2.0
bundle documents are tolerated on decode (see Decode)
but never produced on encode.
import "github.com/jsonstat/go"A JSON-stat dataset is a multi-dimensional cube. Cells sit at the intersection
of dimensions; the flat value array lists cells in row-major order
("what does not change, first"). The last dimension in id changes fastest.
Every operation in jsonstat-go is a function over the same in-memory model:
- Client: decode → traverse → subset (
Dice) → transform (Unflatten,Transform) → encode. - Authoring: build cubes programmatically with the fluent
Builder. - Validate: structural + semantic tiers, pure Go (see
Validate).
Idiomatic Go, not a port: typed returns + error, functional-options for
configuration, context.Context for cancellation,
log/slog for structured logging, and
iter.Seq2 for lazy iteration. Runtime
dependency is the Go standard library only.
| Constant | Value | Meaning |
|---|---|---|
ClassDataset |
"dataset" |
A dataset response. |
ClassCollection |
"collection" |
A collection response. |
ClassDimension |
"dimension" |
A standalone dimension response. |
ClassBundle |
"bundle" |
Legacy pre-2.0 container; not a valid 2.0 class but recognised by Decode for backwards compatibility. |
Documents without a class are treated as ClassDataset by tolerant decoders.
| Constant | Value | Meaning |
|---|---|---|
PositionStart |
"start" |
Symbol precedes the value (e.g. $5). |
PositionEnd |
"end" |
Symbol follows the value (e.g. 5%; the default). |
const FormatVersion = "2.0" // version.goSee version.go.
All errors are typed sentinels safe to use with
errors.Is and
errors.As. They are typically wrapped inside a
ValueError by Decode,
Validate, and the traversal methods.
| Sentinel | Meaning |
|---|---|
ErrBuildIncomplete |
Builder.Build — missing dimensions, categories, or values. |
ErrCategoryNotFound |
A requested category ID is not present in a dimension. |
ErrCellMissing |
Requested cell has no value (JSON null / absent key). Not an error in the usual sense — callers should test Cell.Missing; the sentinel exists so helpers can wrap it. |
ErrCoordLenMismatch |
A coordinate vector length ≠ dataset dimension count. |
ErrDatasetNotFound |
A requested dataset is not present in the document. |
ErrDimensionNotFound |
A requested dimension ID is not declared. |
ErrEmptyDocument |
Input was empty or whitespace only. |
ErrHTTPFailure |
Fetch — server returned non-2xx. The wrapping ValueError carries the status code in Flat. |
ErrIndexOutOfRange |
A numeric index (dataset index, category index, cell coordinate) is out of range. |
ErrInvalidSize |
The size array is inconsistent (negative entries, length mismatch with id, etc.). |
ErrItemNotFound |
A collection item lookup failed. |
ErrMissingRequired |
A JSON-stat 2.0 required property is absent. |
ErrResponseTooLarge |
Fetch — response body exceeded the limit set by WithMaxBytes. |
ErrSparseValueLength |
A sparse value object contains a key ≥ the dataset's total cell count. |
ErrStatusShape |
The status property is neither a string, an array, nor an object. |
ErrUnknownClass |
The document's class is not one of the JSON-stat 2.0 response classes. |
ErrUnsupportedVersion |
The document's version is below 2.0 and the document does not look like a tolerated pre-2.0 bundle. |
ErrValueShape |
The value property is neither an array nor an object, or the resolved flat index is out of range. |
func Decode(r io.Reader) (*Document, error)Parses a JSON-stat 2.0 document from r. Accepts all three 2.0 response classes
(dataset, collection, dimension) and tolerates the pre-2.0 bundle container.
Normalises dense/sparse value and all three status forms. Structural shape is
checked; semantic checks live in Validate.
func DecodeBytes(b []byte) (*Document, error)Like Decode but accepts a byte slice.
func Fetch(ctx context.Context, url string, opts ...FetchOption) (*Document, error)Context-aware counterpart of Decode for remote HTTP
sources. Default client has a 30-second timeout; supply
WithHTTPClient for pooling / mTLS / custom transports.
doc, err := jsonstat.Fetch(ctx, url,
jsonstat.WithUserAgent("my-app/1.0"),
jsonstat.WithMaxBytes(50*1024*1024), // 50 MiB guard
)| Function | Returns | Notes |
|---|---|---|
Encode(w *bytes.Buffer, doc *Document) error |
error | Compact wire form, canonical JSON-stat property ordering. Supports single-dataset / collection / dimension. Pre-2.0 bundles are rejected. |
EncodeBytes(doc *Document) ([]byte, error) |
[]byte |
Like Encode but returns bytes. |
MarshalDocument(doc *Document) ([]byte, error) |
[]byte |
Functional inverse of DecodeBytes. |
MarshalDataset(ds *Dataset) ([]byte, error) |
[]byte |
JSON-stat wire form of a single dataset. |
MarshalCollection(c *Collection) ([]byte, error) |
[]byte |
JSON-stat wire form of a collection. |
MarshalDimension(dim *Dimension) ([]byte, error) |
[]byte |
JSON-stat wire form of a standalone dimension-class response. |
Each type also satisfies json.Marshaler
directly ((*Dataset).MarshalJSON, etc.), so it can be embedded in other JSON
structures.
func Validate(doc *Document) []ValidationErrorRuns structural + semantic tiers over doc and returns every problem found,
in path order. An empty/nil slice means valid. Never panics; a nil document
yields a single CodeMissingClass error. Problems are
never silently dropped: a single missing property may cascade into several
errors, all of which are surfaced.
func ValidateDataset(ds *Dataset, prefix string) []ValidationErrorSame as Validate but for a single dataset. The
prefix is prepended to every reported Path so bundle/collection members can
be distinguished.
func FormatValidationReport(errs []ValidationError) stringRenders a slice of validation errors as a path-sorted multi-line string. Useful for CLI output and test failure messages.
var Version = "0.1.1" // version.go — overridable via -ldflags
func VersionInfo() map[string]string // → {"library","version","jsonstat","go","spec","license"}VersionInfo is intended for diagnostics, /version
endpoints, and CLI banners.
func CoordinatesCategoryKey(prefix string, catIndex int) stringReturns the string key under which a category's coordinates would be stored in the source JSON-stat object. Exported as a helper for tests that build synthetic fixtures programmatically.
Type Cell
A single value-status pair read out of a cube. Return type of the cell-access
methods on Dataset.
| Field | Type | Meaning |
|---|---|---|
Value |
float64 |
Numeric observation. Always 0 when Missing is true. |
Status |
string |
Observation-level status code. May be empty. |
Missing |
bool |
Cell has no value (JSON null in dense form, or absent key in sparse). |
Flat |
int |
Row-major flat index. Always ≥ 0. |
Coords |
[]int |
Per-dimension category index, in Dataset.ID order. |
func (c Cell) HasValue() bool // reports whether the cell carries a numeric observationMissing cells: Value is the zero float64 and Missing is true; callers
should test Missing before reading Value.
Type Category
One possible value of a Dimension.
| Field | Type | Meaning |
|---|---|---|
ID |
string |
Identifier, unique within its dimension. |
Index |
int |
0-based position — used directly in flat-index math. |
Label |
string |
Human-readable name (may be empty). |
Unit |
*Unit |
Unit metadata (typically only on metric-role categories). |
Coordinates |
[]float64 |
[longitude, latitude] pair for geo-role categories; nil when absent. |
Type Dimension
One axis of a dataset's cube.
| Field | Type | Meaning |
|---|---|---|
ID |
string |
Identifier matching one entry of Dataset.ID. |
Label |
string |
Human-readable name. |
Role |
Role |
Special role, or empty when unset. |
Size |
int |
Number of categories. Equals Dataset.Size[i]. |
Categories |
[]Category |
Categories in index order. |
Child |
map[string][]string |
Category hierarchy: parent ID → child IDs. nil if none. See spec. |
Href |
string |
URL of the standalone dimension response, if any. |
Link |
[]Link |
Related-resource links (e.g. alternate geo breakdowns). |
Note |
[]string |
Dimension-level notes. |
Extension |
map[string]any |
Provider-specific extra fields. |
| Method | Signature | Notes |
|---|---|---|
CategoryByID |
(id string) (*Category, error) |
Returns the category or ErrCategoryNotFound. |
CategoryIndex |
(id string) (int, error) |
0-based position or ErrCategoryNotFound. |
CategoryIDs |
() []string |
IDs of every category in index order. |
CategoryLabels |
() []string |
Labels in index order; unlabelled categories render under their ID. Go counterpart of JS Dimension(id, true). |
HasHierarchy |
() bool |
Reports category.child presence. |
ChildrenOf |
(parentID string) ([]string, bool) |
Child IDs (defensive copy) or false. |
Type Dataset
The primary type of the package: every read, traverse, subset, transform, and
serve operation is a function over a *Dataset. Normalises the polymorphic
parts of the wire format (value dense/sparse, status string/array/object).
| Field | Type | Meaning |
|---|---|---|
Class |
string |
Always ClassDataset. |
Version |
string |
JSON-stat version declared on source, or FormatVersion for Builder-built datasets. |
Label, Href, Source, Updated |
string |
Standard metadata. Updated stored as raw string to avoid tz pitfalls. |
ID |
[]string |
Ordered dimension IDs; order determines stride math. |
Size |
[]int |
Category count per dimension, parallel to ID. |
Role |
map[Role][]string |
Declared roles → dimension IDs. May be empty. |
Dimensions |
map[string]*Dimension |
Dimensions keyed by ID. |
Note |
[]string |
Dataset-level notes. |
Link |
[]Link |
Related-resource links. |
Extension |
map[string]any |
Provider-specific extra fields. |
| Method | Signature | Notes |
|---|---|---|
N |
() int |
Total cell count (product of Size). Counterpart of JS n. Returns 0 if no dimensions or any size is 0. |
DimCount |
() int |
Number of dimensions. |
Dimension |
(id string) (*Dimension, error) |
Or ErrDimensionNotFound. |
DimensionByIndex |
(i int) (*Dimension, error) |
Or ErrIndexOutOfRange. |
DimensionByRole |
(role Role) (*Dimension, error) |
First dimension with that role, or ErrDimensionNotFound. |
DimensionsByRole |
(role Role) []*Dimension |
All dimensions with that role, in ID order. |
DimensionPosition |
(id string) (int, error) |
Index in ID. |
DimensionIDs |
() []string |
Defensive copy of ID. |
SizeSlice |
() []int |
Defensive copy of Size. |
Roles |
() []Role |
Declared roles. |
HasRole |
(role Role) bool |
Reports role presence. |
Strides |
() []int |
Cached strides (defensive copy). nil before reindex. |
ValueFormat |
() string |
Which value wire form would be emitted on encode. |
StatusFormat |
() string |
Which status wire form would be emitted on encode. |
| Method | Signature | Notes |
|---|---|---|
CellByFlat |
(i int) (Cell, error) |
Cell at flat row-major index. Counterpart of JS Dataset.Data(i). |
CellByCoord |
(coords ...int) (Cell, error) |
Cell at one category index per dim, in ID order. Counterpart of JS Dataset.Data([0,0,0]). |
CellByLabel |
(m map[string]string) (Cell, error) |
Cell at dim-ID → cat-ID. Counterpart of JS Dataset.Data({TIME:2020, GEO:"ES"}). |
Cells |
() iter.Seq2[Cell, error] |
Lazy Go 1.23 range-over-func; yields exactly N cells. Counterpart of JS Dataset.Data(). |
CellsSlice |
() ([]Cell, error) |
Materialises the full cube as a slice. |
Walk |
(fn func(Cell) error) error |
Callback iteration; stops at first non-nil error. |
| Method | Signature | Notes |
|---|---|---|
Dice |
(f Filter, opts ...DiceOption) (*Dataset, error) |
The single subsetting operation (no Slice). Returns a fresh reindexed dataset. |
Unflatten |
(fn UnflattenFunc) ([]any, error) |
Faithful JS port; callback-driven raw cell stream. |
Transform |
(opts ...TransformOption) (any, error) |
Faithful JS port; options-driven tabular output (array / arrobj / objarr / object). |
func (d *Dataset) MarshalJSON() ([]byte, error)Satisfies json.Marshaler so the
dataset can be embedded or marshalled directly.
Type Document
The top-level parsed value of a JSON-stat response. Exactly one of the
class-specific fields is populated, depending on Class:
| Field | Type | Populated when |
|---|---|---|
Class |
string |
Always — one of the Class* constants. |
Version |
string |
Always. |
Label, Href, Note, Link, Extension |
various | Document-level metadata. |
Dataset |
*Dataset |
Class == ClassDataset (also when class is omitted but required dataset properties are present). |
Collection |
*Collection |
Class == ClassCollection. |
Dimension |
*Dimension |
Class == ClassDimension. |
Bundle |
map[string]*Dataset |
Pre-2.0 bundle (no class, top-level values look like datasets). Keyed by dataset id. |
IsBundle |
bool |
Document was decoded as a pre-2.0 bundle. |
| Method | Signature | Notes |
|---|---|---|
IsDataset |
() bool |
|
IsCollection |
() bool |
|
IsDimension |
() bool |
|
Datasets |
() []*Dataset |
Every dataset regardless of class: single dataset → one-element slice; collection → embedded datasets; bundle → bundled datasets in id-key order. |
SingleDataset |
() (*Dataset, error) |
Convenience: returns Dataset or ErrDatasetNotFound. |
MarshalJSON |
() ([]byte, error) |
Dispatches on the populated response-class field. |
Type Collection
In-memory representation of a JSON-stat collection response: an ordered list
of Item values, each of which may embed or link to a dataset,
dimension, or another collection.
| Field | Type | Meaning |
|---|---|---|
Label, Href, Updated, Source |
string |
Standard metadata. |
Note |
[]string |
Collection-level notes. |
Link |
[]Link |
Links; items appear here with rel "item". |
Extension |
map[string]any |
Provider-specific extra fields. |
Items |
[]Item |
Parsed item list, in declaration order. |
| Method | Signature | Notes |
|---|---|---|
ItemByIndex |
(i int) (*Item, error) |
i-th item or ErrItemNotFound. |
ItemByID |
(id string) (*Item, error) |
First item whose Item.ID matches; exact-string equality. |
ItemsByClass |
(class string) []*Item |
Items whose embedded class matches (e.g. ClassDataset). |
Datasets |
() []*Dataset |
Every embedded dataset; link-only items are skipped. |
MarshalJSON |
() ([]byte, error) |
Type Item
One entry in a JSON-stat collection. Items may embed a full dataset/dimension or
merely link via Href.
| Field | Type | Meaning |
|---|---|---|
Href |
string |
URL when referenced rather than embedded. |
Type |
string |
MIME type at Href. |
Label |
string |
Human-readable title. |
Class |
string |
Embedded item's class (e.g. "dataset"). |
ID |
string |
Optional item identifier inside the collection. |
Extension |
map[string]any |
Provider-specific extra fields. |
EmbeddedDataset |
*Dataset |
Non-nil when the item embeds a full dataset. |
EmbeddedDimension |
*Dimension |
Non-nil when the item embeds a standalone dimension. |
func (i *Item) IsEmbedded() bool // reports an embedded response rather than only a linkType Link
A single entry in a JSON-stat link array. Used at every level: document,
dataset, dimension, category.
| Field | Type | Meaning |
|---|---|---|
Href |
string |
Target URL. |
Type |
string |
MIME type of the resource at Href (e.g. application/json-stat). |
Rel |
string |
IANA link relation type (self, item, alternate, version, note). |
Label |
string |
Human-readable description. |
Extension |
map[string]any |
Arbitrary extra keys beyond href/type/rel/label. |
See spec.
Type Role
type Role stringNames a special meaning assigned to a dimension via the dataset's role object.
JSON-stat 2.0 defines exactly three:
| Constant | Value | Meaning |
|---|---|---|
RoleTime |
"time" |
Points or periods in time (e.g. "2020", "2021-Q1"). |
RoleGeo |
"geo" |
Spatial dimension (country codes, NUTS regions). |
RoleMetric |
"metric" |
Names the quantity being measured (e.g. "POP", "GDP"). Metric categories typically carry a Unit. |
See spec.
Type Unit
Unit of measure attached to a metric category.
| Field | Type | Meaning |
|---|---|---|
Decimals |
int |
Recommended display decimal places (required by spec when unit is present; enforced by Validate, not the type). |
Label |
string |
Human-readable unit label (persons, euros). |
Symbol |
string |
Unit symbol ($, %, €). |
Position |
string |
PositionStart or PositionEnd (default). |
See spec.
Type Filter
type Filter map[string][]stringSelects the categories to keep (or, with WithDropFilter,
exclude) during a Dice operation. Keyed by dimension ID; each value is
the list of category IDs to retain (or drop). A dimension absent from the map is
left untouched. Unknown category IDs cause
ErrCategoryNotFound. Duplicate IDs and ordering are
ignored: the result always preserves the original category order of the source.
Fluent constructor for Dataset instances — the Go-native
authoring counterpart of Decode.
ds, err := jsonstat.NewBuilder().
Label("Population by sex and year").
Dim("sex", "Sex").Cat("F", "Female").Cat("M", "Male").End().
Dim("year", "Year").Cat("2020", "").Cat("2021", "").End().
Values([]float64{100, 110, 200, 210}). // [F2020, F2021, M2020, M2021]
Build()Values are interpreted in JSON-stat row-major order (last declared dimension
varies fastest). Use SparseValues for sparse input; the
resulting dataset encodes back to the sparse form.
| Method | Signature | Notes |
|---|---|---|
NewBuilder |
() *Builder |
Returns an empty builder. |
Label |
(s string) *Builder |
Dataset title. |
Source |
(s string) *Builder |
Source attribution. |
Updated |
(s string) *Builder |
Last-updated timestamp (stored verbatim; callers format ISO 8601). |
Href |
(s string) *Builder |
Canonical URL. |
Note |
(s string) *Builder |
Appends a free-text note. |
Extension |
(key string, value any) *Builder |
Provider-specific extension field. |
| Method | Signature | Notes |
|---|---|---|
Dim |
(id, label string) *DimBuilder |
Begins a new dimension; subsequent Cat calls add categories. |
DimBuilder.End |
() *Builder |
Closes the dimension, returns the parent Builder. |
DimBuilder.Cat |
(id, label string) *DimBuilder |
Appends a category (empty label allowed). |
DimBuilder.CatWith |
(c catSpec) *DimBuilder |
Richer per-category metadata entry point (unit, coordinates). |
DimBuilder.Role |
(r Role) *DimBuilder |
Declares the role (time/geo/metric); multiple dims may share a role. |
DimBuilder.Unit |
(u *Unit) *DimBuilder |
Attaches a Unit to the most recently added category. |
DimBuilder.Coordinates |
(lon, lat float64) *DimBuilder |
Attaches a [lon, lat] pair to the most recently added category (geo dims). |
| Method | Signature | Notes |
|---|---|---|
Values |
(vals []float64) *Builder |
Dense value array; length must equal product of category counts. Every cell present. |
DenseValuesWithMissing |
(vals []float64, missing []bool) *Builder |
Like Values but a parallel missing slice marks absent observations (JSON null). |
SparseValues |
(m map[int]float64) *Builder |
Sparse object form; only supplied flat-index/value pairs are present. Encodes back to sparse. |
UniformStatus |
(s string) *Builder |
Single status string for every cell. Most compact form; overrides earlier status calls. |
StatusArray |
(arr []string) *Builder |
Per-cell status in array form (row-major). Empty string = no status. |
StatusMap |
(m map[int]string) *Builder |
Per-flat-index status in object form. |
Build |
() (*Dataset, error) |
Materialises the cube. Validates: ≥1 dim, every dim ≥1 category, dense value length, sparse keys in range. Returns a fully reindexed dataset. The builder is not mutated and may be reused. |
Type Datapoint
Value/status pair exposed to the UnflattenFunc callback
for the current cell. When the cell has no status, Status is "" (Go-friendly
counterpart of the JS null). When missing, Value is 0 and Missing is
true.
Type Coordinates
type Coordinates map[string]stringDimension-ID → category-ID map exposed to the
UnflattenFunc callback for the current cell. Freshly
allocated per cell so the callback may retain references safely. Category IDs
are always strings (e.g. {"year": "2012"}, not 2012).
Type UnflattenFunc
type UnflattenFunc func(coords Coordinates, dp Datapoint, n int, row []any) anyMirrors the JS Toolkit's Unflatten callback. Invoked once per cell in
row-major order.
| Argument | Meaning |
|---|---|
coords |
Coordinates of the cell (dim ID → cat ID). |
dp |
Cell's value/status pair (Datapoint). |
n |
0-based cell counter (flat row-major index). |
row |
Accumulator slice being built; the returned value is appended after the callback returns. |
Returning nil skips the cell (matching the JS Toolkit's treatment of a
callback that returns undefined).
out, err := ds.Unflatten(func(coords jsonstat.Coordinates, dp jsonstat.Datapoint, n int, row []any) any {
return map[string]any{"coordinates": coords, "datapoint": dp}
})Type TransformType
type TransformType stringSelects the output shape of Transform. Mirrors JS opts.type.
| Constant | Value | Output Go type | Notes |
|---|---|---|---|
TransformArray |
"array" |
[][]any |
Default. Header row + data rows. |
TransformArrObj |
"arrobj" |
[]map[string]any |
One object per cell. Supports by (pivot) and meta. |
TransformObjArr |
"objarr" |
map[string][]any |
Columnar. Supports by and meta. |
TransformObject |
"object" |
*DataTable |
Google DataTable {cols, rows}. Infers column type from first value. |
When WithMeta is true, the array/objarr shapes are wrapped in
*TableWithMeta carrying the metadata block, matching
the JS {meta, data} shape. The object type never emits metadata.
Type Content
type Content stringControls whether categories are identified by label or by ID in
Transform output.
| Constant | Value | Meaning |
|---|---|---|
ContentLabel |
"label" |
(Default) human-readable label. |
ContentID |
"id" |
Category ID. |
Type Field
type Field stringControls whether dimension/value/status column keys are IDs or labels. Default
FieldID; the array type overrides this to
FieldLabel.
| Constant | Value | Meaning |
|---|---|---|
FieldID |
"id" |
Key columns by IDs. |
FieldLabel |
"label" |
Key columns by labels. |
Type DataTable and friends
Produced by Transform with the TransformObject
type. Mirrors the Google DataTable shape.
type DataTable struct { Cols []DataTableCol; Rows []DataTableRow }
type DataTableCol struct { ID, Type, Label string }
type DataTableRow struct { C map[string]any } // cells carry value in "v"; "f" not populatedType TableMeta and friends
Emitted when WithMeta is true.
type TableWithMeta struct { Meta TableMeta; Data any }
type TableMeta struct { Type, Label, Source, Updated, By, Prefix string; ID []string; Status, Comma bool; Drop []string; Dimensions map[string]TableDimMeta }
type TableDimMeta struct { Label, Role string; Categories TableDimCategories }
type TableDimCategories struct { ID, Label []string }Type ValueError
Carries context about where in the cube an error occurred. The structured
wrapping type used by Decode, Validate,
and the traversal methods. Recover with
errors.As.
| Field | Type | Meaning |
|---|---|---|
Op |
string |
Operation that failed (e.g. "Decode", "Dataset.Dimension"). |
Dim |
string |
Dimension ID involved, if any. |
Cat |
string |
Category ID involved, if any. |
Flat |
int |
Flat row-major cell index involved. -1 = not applicable. |
Err |
error |
Wrapped sentinel / underlying error. |
func (v *ValueError) Error() string
func (v *ValueError) Unwrap() errorType ValidationCode
type ValidationCode stringStable kebab-case identifier for a single class of validation problem. The set is intentionally small; each identifies a single invariant regardless of tier. Tests and downstream tooling can rely on these strings not changing across releases.
| Code | Constant | Meaning |
|---|---|---|
missing-class |
CodeMissingClass |
No class property and not a tolerated pre-2.0 bundle. |
unknown-class |
CodeUnknownClass |
class not one of dataset/collection/dimension. |
missing-required |
CodeMissingRequired |
A JSON-stat 2.0 required property is absent. |
id-size-mismatch |
CodeIDSizeMismatch |
len(id) != len(size). |
dim-missing |
CodeDimMissing |
A dimension named in id is absent from dimension. |
dim-extra |
CodeDimExtra |
dimension has a key not present in id (the only permissive warning). |
category-size-mismatch |
CodeCategorySizeMismatch |
A dimension's category count ≠ its size. |
invalid-size |
CodeInvalidSize |
size has a negative element or is malformed. |
value-length-mismatch |
CodeValueLengthMismatch |
Dense value length ≠ prod(size). |
sparse-value-key-out-of-range |
CodeSparseValueKeyOutOfRange |
Sparse value key ≥ prod(size). |
status-length-mismatch |
CodeStatusLengthMismatch |
status array length ≠ prod(size). |
role-unknown-dim |
CodeRoleReferencesUnknownDim |
role names a dimension not in id. |
duplicate-category-id |
CodeDuplicateCategoryID |
A dimension has two categories with the same ID. |
duplicate-dim-id |
CodeDuplicateDimID |
id contains the same dimension ID twice. |
Type ValidationError
Describes a single validation problem. Returned by Validate /
ValidateDataset as a slice (empty when valid).
| Field | Type | Meaning |
|---|---|---|
Code |
ValidationCode |
Stable identifier. |
Path |
string |
Dotted-path location (dimension.geo.category.index, value[3]); empty = whole document. |
Message |
string |
Human-readable description. |
Err |
error |
Underlying sentinel (one of the Err* values). |
func (v *ValidationError) Error() string
func (v *ValidationError) Unwrap() error
func (v *ValidationError) HasSeverity() string // "fatal" except for CodeDimExtra (permissive warning)Transform options (TransformOption)
| Option | Effect |
|---|---|
WithTransformType |
Sets the output shape. Default TransformArray. |
WithStatus |
Includes the status column. Default false. Ignored when WithBy is also set. |
WithContent |
Label vs ID for categories. Default ContentLabel. |
WithField |
ID vs label for dimension/value/status keys. Default FieldID (array type overrides to FieldLabel). |
WithValueLabel |
Label of the value column. Default "Value". |
WithStatusLabel |
Label of the status column. Default "Status". Only relevant when WithStatus is true. |
WithMeta |
Attaches dataset metadata, wrapping as *TableWithMeta. Default false. Not available with the object type. |
WithBy |
Pivots the value column on a dimension (one output column per category). arrobj/objarr only; silently ignored for array/object. Non-existent dims are ignored. |
WithPrefix |
Prefix prepended to pivoted category columns. Default "". |
WithDrop |
Excludes dimension IDs from output. Only single-category dims are droppable; invalid/multi-category IDs are ignored. |
WithComma |
Formats numbers with a comma decimal mark. Default false. Not available with the object type. |
Dice options (DiceOption)
| Option | Effect |
|---|---|
WithDropFilter |
Inverts Filter: listed categories are removed rather than retained. Dims absent from the filter are still untouched. |
WithClone |
Controls deep copy vs in-place mutation. Default true (clone); false is an opt-in optimisation for callers that will not reuse the receiver. |
Fetch options (FetchOption)
| Option | Effect |
|---|---|
WithHTTPClient |
Supplies the http.Client. Default: per-call client with 30s timeout. |
WithHeader |
Sets/overrides a single request header. Multiple calls with different keys accumulate; same key replaces. Host cannot be set this way. |
WithUserAgent |
Sets the User-Agent header. Default jsonstat-go/+Version. |
WithMaxBytes |
Caps response body bytes; exceeded → ErrResponseTooLarge. 0 = unlimited. |
WithMethod |
Overrides HTTP method. Default GET. With POST, supply WithBody. |
WithBody |
Supplies a request body for non-GET methods. Caller sets Content-Type via WithHeader. |
import "github.com/jsonstat/go/jsonstathttp"Serves a JSON-stat Dataset over
net/http with query-string subsetting, content
negotiation, conditional GET (ETag / If-None-Match), and slog access logging.
Go counterpart of the server-side helpers shipped with the JS JSON-stat Toolkit.
A single constructor returns an
http.Handler ready to mount on any
ServeMux. All heavy lifting is
delegated to the core jsonstat package.
func NewHandler(ds *jsonstat.Dataset, opts ...HandlerOption) http.HandlerThe dataset is concurrency-safe: the handler never mutates it (Dice
returns a fresh Dataset).
h := jsonstathttp.NewHandler(ds, jsonstathttp.WithLogger(log))
http.ListenAndServe(":8080", h)func ParseQuery(q urlQuery) (jsonstat.Filter, error)Extracts a subsetting Filter from a request's query string.
Returns (nil, nil) when no subsetting parameters are present (the handler then
serves the full dataset). Invalid filters return a non-nil error wrapping
ErrInvalidQuery (safe to surface as HTTP 400).
Handler options (HandlerOption)
| Option | Effect |
|---|---|
WithLogger |
slog.Logger for access logging. Default slog.Default. |
WithETagPrefix |
Prefix prepended to the ETag value. Default "jsonstat". Useful when serving multiple datasets on one origin. |
WithIndentJSON |
Pretty-prints (2-space) JSON for json-stat and plain-JSON representations. Default compact. Debug aid — roughly doubles response size. |
WithStatusColumn |
Includes the status column in CSV/CSV-stat output. Default omits status (matching the JS Toolkit default). |
WithDefaultRepresentation |
Changes the representation served when no Accept / ?format= signal is present. Default RepJSONStat. |
WithoutETag |
Disables ETag emission and If-None-Match handling. For tests asserting on bodies. |
Type Representation
type Representation intCarries the response Content-Type and a discriminator the handler switches on
to pick the encoder.
| Constant | Content-Type | Notes |
|---|---|---|
RepJSONStat |
application/json-stat |
Default. |
RepJSON |
application/json |
Plain JSON view. |
RepCSVStat |
text/csv-stat |
CSV-stat flavour. |
RepCSV |
text/csv |
Plain CSV. |
func (r Representation) ContentType() string // HTTP Content-Type (no parameters)
func (r Representation) IsCSV() bool // one of the CSV flavours (shared encoder)
func (r Representation) String() string // human-readable label for loggingContent negotiation honours Accept q-values and the ?format= query override
(json-stat, json, csv-stat, csv).
import "github.com/jsonstat/go/internal/stride" // internal — reached via Dataset methodsImplements the row-major ("what does not change, first") index math. The cell at
coordinates (c₀, c₁, …, cₙ₋₁) — where cᵢ is the category index of dimension
i — is stored at:
flat(c₀, c₁, …, cₙ₋₁) = Σᵢ cᵢ · strideᵢ
where strideᵢ = ∏ⱼ sizeⱼ for j > i. The last dimension changes fastest. See
Row-major order and the
canonical JSON-stat sample.
This package is internal; callers reach it through the methods on
Dataset. All public-facing APIs accept dimension IDs and
category indices, never raw strides.
| Function | Signature | Notes |
|---|---|---|
ValidateSize |
(size []int) error |
Non-empty and every element non-negative. Zero-size allowed (denotes empty dimension → total 0). |
Total |
(size []int) (int, error) |
Product of all sizes. |
Strides |
(size []int) ([]int, error) |
Per-dimension stride; last is always 1. E.g. [1, 36, 12] → [432, 12, 1]. |
Flat |
(size, coords []int) (int, error) |
Coordinates → flat position. |
Coords |
(size []int, flat int) ([]int, error) |
Inverse of Flat. |
Inc |
(size, coords []int) (next []int, carry bool, err error) |
Advances a coordinate vector by one cell in-place; carry true when wrapped back to all-zero. |
AllCoords |
(size []int) ([][]int, error) |
Full enumeration in row-major order (tests/small cubes). |
| Sentinel | Meaning |
|---|---|
ErrEmptySize |
size slice is empty. |
ErrNegativeSize |
Some element of size is negative. |
ErrCoordLenMismatch |
Coordinate count ≠ dimension count. |
ErrCoordOutOfRange |
Coordinate negative or ≥ corresponding size. |
ErrIndexOutOfRange |
Flat index negative or ≥ total. |
go install ./cmd/jsonstat # from a module checkout
make install-cli # injects the VCS version via -ldflagsThe CLI is a thin shell over the jsonstat and
jsonstathttp packages. Subcommands:
| Subcommand | Purpose |
|---|---|
decode <file> |
Decode a JSON-stat document and print a summary of its structure. |
validate <file> |
Run Validate and print a FormatValidationReport. |
convert <in> <out> -f <format> |
Convert between formats (csv, csv-stat, json). Optional -status flag. |
slice <file> -f <filter> |
Subset a dataset via Dice and print the result. |
serve <file> [addr] |
Serve a dataset over HTTP via jsonstathttp.NewHandler. |
version |
Print jsonstat <Version> (JSON-stat <FormatVersion>). |
See cmd/jsonstat/main.go for flag details.
The repository ships three runnable examples under examples/:
| Example | Demonstrates |
|---|---|
examples/basic-read |
End-to-end client flow: Decode → traverse → Dice → Transform. |
examples/build-cube |
Build a 3-dimensional cube with the Builder (per-category units, object-form status), MarshalDataset, round-trip decode. |
examples/serve-http |
Build a toy dataset in-memory and serve it over HTTP with jsonstathttp.NewHandler. |
Apache-2.0. See LICENSE.