nupp.serde.codec

A new codec uses these helpers to apply the number, timestamp, error-path, and context rules the built-in codecs share. It implements nupp.serde.Writer and nupp.serde.Reader itself; see Serialization bindings for where a codec sits beside a model library.

A codec that follows these rules accepts and rejects the same values as nupp.serde.json and nupp.serde.native, so a binding behaves the same whichever one carries it.

local codec = require("nupp.serde.codec")
assert(codec.integer("255", 8, false).decimal == "255")
assert(not pcall(codec.integer, "256", 8, false))
assert(codec.formatDateTime(codec.parseEpoch("86400")) == "1970-01-02T00:00:00Z")

Module contents

Types

TypeKindDescription
ContextBuilderrecordCollects the values of a nupp.serde.Context before it is frozen.

Functions

FunctionKindDescription
contextBuilderfunctionStarts a context for what a codec reads.
discardFailedfunctionDiscards a value a codec decoded and then has to reject, returning the failure to raise.
floatfunctionRounds a number to a float width and checks it is finite.
formatDateTimefunctionFormats a timestamp as an RFC 3339 date-time in UTC.
formatEpochfunctionFormats a timestamp as epoch seconds.
integerfunctionChecks an integer lexeme against a width and signedness.
parseDateTimefunctionParses an RFC 3339 date-time.
parseEpochfunctionParses epoch seconds, with an optional fraction.
prefixErrorfunctionPrefixes a failure's path with its parent's.
wrapErrorfunctionWraps any failure as a nupp.serde.Error at a path.

Types#

ContextBuilderrecord#

record ContextBuilder ...

Collects the values of a nupp.serde.Context before it is frozen.

Members

NameKindDescription
codecfield
profilefield
parentfield
valuesfield
frozenfield
setmethodStores a value under a key, replacing any value set before.
freezemethodReturns the context holding the values set so far.

codecfield#

codec: table
@private@readonly

profilefield#

@private@readonly

parentfield#

parent: core.Context?
@private@readonly

valuesfield#

values: {[unknown]: Entry}
@private@readonly

frozenfield#

frozen: boolean
@private

setmethod#

set: function set<V is nupp.Copyable>(self, key: store.Key<V>, value: V): nil

Stores a value under a key, replacing any value set before.

Arguments
NameTypeDescription
selfany
keystore.Key<V>

the key to store under

valueV

the value

Returns
TypeDescription
nil
Raises
TypeCondition
string

when the builder is frozen

freezemethod#

freeze: function freeze(self): core.Context

Returns the context holding the values set so far.

The builder can then no longer change, so the context it returned cannot either. A key the context does not hold is looked up in its parent.

Arguments
NameTypeDescription
selfany
Returns
TypeDescription
core.Context

the context

Raises
TypeCondition
string

when the builder is already frozen

Functions#

contextBuilderfunction#

function contextBuilder(codec: table, profile: table, parent: core.Context?): Builder

Starts a context for what a codec reads.

codec and profile identify where the value came from, so a protocol can refuse to replay a document captured under an incompatible one. Values are set under nupp.util.Keys and must be Copyable.

local codec = require("nupp.serde.codec")
local source: nupp.util.Key<string> = nupp.util.newKey()
local builder = codec.contextBuilder({}, {}, nil)
builder:set(source, "upload.json")
assert(builder:freeze():get(source) == "upload.json")

Arguments

NameTypeDescription
codectable
profiletable
parentcore.Context?

Returns

TypeDescription
Builder

discardFailedfunction#

function discardFailed<T>(owner: core.Discard<T>, takes value: T, cause: unknown): unknown

Discards a value a codec decoded and then has to reject, returning the failure to raise.

When the discard itself fails, its failure is recorded in the error's suppressed list and the original cause is kept.

Type parameters

NameDescription
T

Arguments

NameTypeDescription
ownercore.Discard<T>
takes valueT
causeunknown

Returns

TypeDescription
unknown

floatfunction#

function float(value: number, width: 32 | 64, allowNonfinite: boolean?): number

Rounds a number to a float width and checks it is finite.

Arguments

NameTypeDescription
valuenumber
width32 | 64
allowNonfiniteboolean?

Returns

TypeDescription
number

formatDateTimefunction#

function formatDateTime(borrows value: core.Timestamp): string

Formats a timestamp as an RFC 3339 date-time in UTC.

Arguments

NameTypeDescription
borrows valuecore.Timestamp

Returns

TypeDescription
string

formatEpochfunction#

function formatEpoch(borrows value: core.Timestamp): string

Formats a timestamp as epoch seconds.

Arguments

NameTypeDescription
borrows valuecore.Timestamp

Returns

TypeDescription
string

integerfunction#

function integer(text: string, width: 8 | 16 | 32 | 64, signed: boolean): core.Integer

Checks an integer lexeme against a width and signedness.

Arguments

NameTypeDescription
textstring
width8 | 16 | 32 | 64
signedboolean

Returns

TypeDescription
core.Integer

parseDateTimefunction#

function parseDateTime(text: string): core.Timestamp

Parses an RFC 3339 date-time.

Arguments

NameTypeDescription
textstring

Returns

TypeDescription
core.Timestamp

parseEpochfunction#

function parseEpoch(text: string): core.Timestamp

Parses epoch seconds, with an optional fraction.

Arguments

NameTypeDescription
textstring

Returns

TypeDescription
core.Timestamp

prefixErrorfunction#

function prefixError(problem: unknown, parent: string): Error

Prefixes a failure's path with its parent's.

Arguments

NameTypeDescription
problemunknown

the raised value

parentstring

the path of the enclosing value

Returns

TypeDescription
Error

the error, carrying the combined path

wrapErrorfunction#

function wrapError(problem: unknown, path: string, byte: integer?): Error

Wraps any failure as a nupp.serde.Error at a path.

An existing error is returned unchanged, so wrapping at each level keeps the innermost path.

Arguments

NameTypeDescription
problemunknown

the raised value

pathstring

the logical path to record on a new error

byteinteger?

the input offset to record on a new error, or nil

Returns

TypeDescription
Error

the error