Skip to main content

Typed Value Reference

This page is the detailed reference for TTOON's typed value layer. If you only need a beginner introduction to the two syntaxes, start with Format Overview.

At the structure layer, T-TOON extends TOON from the toon-format project. This page focuses on what TTOON adds on top of that base: the typed value layer and its cross-language semantics.

Terminology

  • typed: the overall design concept that the text encoding of a value carries type semantics directly
  • typed types: the 12 built-in value encodings
  • typed unit: one serialized value fragment that the parser sees directly, such as 123.45m, 2026-03-08, or uuid(...)
  • hex and b64 both represent binary payloads, but they still count as two separate typed types at the text-format level

Typed Value System

Both syntaxes share the same 12 typed value encodings:

TypeSyntaxExamplesNotes
nullKeywordnullNull value
boolKeywordtrue, falseLowercase only
intDigits with optional sign and _ separators42, -1_000, 0Sign prefixes and _ separators allowed
floatDecimal point or scientific notation3.14, 1e-9, -0.5, inf, -inf, nanSpecial values: inf, -inf, nan
decimalDigits with m suffix123.45m, 0.00m, -99.9mLowercase m; no scientific notation
stringDouble-quoted"Alice", "hello\nworld"Always double-quoted
dateYYYY-MM-DD2026-03-08Bare in both syntaxes
timeHH:MM:SS[.fractional]14:30:00, 14:30:00.123456Up to microsecond precision
datetimeISO 86012026-03-08T14:30:00, 2026-03-08T14:30:00+08:00, 2026-03-08T14:30:00ZOptional timezone
uuiduuid(...) wrapperuuid(550e8400-e29b-41d4-a716-446655440000)Lowercase hex only
hexhex(...) wrapperhex(4A42), hex(48656C6C6F)Hexadecimal binary encoding
b64b64(...) wrapperb64(SkI=), b64(SGVsbG8=)Base64 binary encoding

Why These 12 Typed Types

TTOON typed types are not copied from any single database or language type system. They are chosen as the practical intersection across mainstream RDBMSs, Arrow, and the Python / JS / Rust SDKs.

The goal is a type layer that is:

  • sufficient for common cross-system data interchange
  • stable across both the object path and the Arrow path
  • portable without binding the format to vendor-specific database types

For that reason, types such as jsonb, enum, interval, array, geospatial types, or money are not built-in typed types. They should be handled by higher-level schema conventions or custom codecs.

Key Rules

  • Strings are always quoted: all string values use double quotes "..." to eliminate bare-token ambiguity
  • Decimal uses m suffix: 123.45m is exact decimal; 123.45 is float
  • UUID and binary use wrappers: uuid(...), hex(...), b64(...)

Type Details

null

null is a single keyword representing the absence of a value.

bool

true and false are the only valid boolean forms. They must be lowercase.

int

Integer values allow an optional sign prefix and _ digit separators:

42
-1_000_000
0

JS precision note: JS native number safely represents integers only within -(2^53 - 1) to 2^53 - 1. Values outside this range throw by default. Use intBigInt() or intNumber({ overflow: 'lossy' }) as needed. See JS Codecs & Int64.

float

Floating-point values must contain a decimal point or use scientific notation:

3.14
1e-9
-0.5
inf
-inf
nan

decimal

Exact decimal values use a lowercase m suffix:

123.45m
0.00m
-99.9m

Scientific notation is not used for decimal. 123.45m is decimal; 123.45 is float.

string

Strings are always double-quoted:

"Alice"
"hello world"
""

Escape rules:

  • T-TOON: only \\, \", \n, \r, \t are allowed
  • T-JSON: full JSON escape set, including \uXXXX, \b, \f

date

YYYY-MM-DD format, bare in both syntaxes:

2026-03-08

time

HH:MM:SS with optional fractional seconds up to microsecond precision:

14:30:00
14:30:00.123456

datetime

ISO 8601 format with optional timezone:

2026-03-08T14:30:00
2026-03-08T14:30:00+08:00
2026-03-08T14:30:00Z

uuid

UUID values use uuid(...):

uuid(550e8400-e29b-41d4-a716-446655440000)

The UUID must use the standard 8-4-4-4-12 shape and lowercase hex only.

hex / b64

Binary payloads can use either hexadecimal or Base64 text:

hex(48656C6C6F)
b64(SGVsbG8=)

hex and b64 map to the same runtime concept of binary data. The difference exists only in the text encoding.

Cross-Language Mapping (Object Path)

Typed TypePython loads()JS parse() DefaultJS with Codec
nullNonenull
boolboolboolean
intintnumber (throws if unsafe)bigint via intBigInt()
floatfloatnumber
decimaldecimal.Decimalstring (stripped m)Decimal class via codec
stringstrstring
datedatetime.datestringCustom via codec
timedatetime.timestringCustom via codec
datetimedatetime.datetimestringCustom via codec
uuiduuid.UUIDstringCustom via codec
hex/b64bytesUint8ArrayCustom via codec

Why JS Returns Strings for Some Types

JS has no native Decimal, UUID, date-only, or time-only types. Returning strings by default avoids:

  • forcing third-party dependencies
  • divergent assumptions between browser and Node.js runtimes

Use use() to register richer codecs. See JS Codecs & Int64.

Arrow Path

Typed TypePython read_arrow()JS readArrow()Arrow Native Type
nullNullable columnNullable columnNull or nullable typed column
boolBooleanBoolBoolean
intInt64Int64Int64
floatFloat64Float64Float64
decimalDecimal128/256DecimalDecimal128 or Decimal256
stringUtf8Utf8Utf8
dateDate32DateDayDate32
timeTime64(Microsecond)TimeMicrosecondTime64(Microsecond)
datetimeTimestamp(μs[, tz])TimestampMicrosecondTimestamp(Microsecond[, tz])
uuidFixedSizeBinary(16)FixedSizeBinary(16)FixedSizeBinary(16) + UUID metadata
hex/b64BinaryBinaryBinary / LargeBinary / FixedSizeBinary

Arrow Type Preservation

  • decimal uses Decimal128 or Decimal256, not Utf8
  • uuid uses FixedSizeBinary(16) with UUID metadata, not Utf8
  • datetime preserves timezone information when present
  • all-null columns infer as Null

Datetime Timezone Behavior

  • timezone-aware and naive datetimes cannot be mixed in the same column
  • the JS Arrow bridge enforces this and raises a schema inference error on mixing
  • timezone-aware datetime uses Timestamp(Microsecond, tz)
  • naive datetime uses Timestamp(Microsecond)

Practical Read / Write Guidance

  • decimal should usually remain an exact numeric database column instead of being downgraded to float
  • uuid can use native types directly in PostgreSQL and SQL Server; MySQL and SQLite commonly rely on binary(16) or text conventions
  • date / time / datetime in SQLite are usually application-level conventions, not strong native types
  • hex and b64 usually map back to the same binary database column type

Mainstream RDBMS Mapping

TTOON typed typeSemantic meaningPostgreSQLMySQL / MariaDBSQLiteSQL ServerNotes
nullmissing valueNULLNULLNULLNULLuniversal
boolboolean flagbooleanboolean / tinyint(1)INTEGER 0/1 or BOOLEAN aliasbitSQLite has no separate boolean storage class
intsigned integersmallint / integer / biginttinyint / smallint / int / bigintINTEGERsmallint / int / bigintTTOON does not define unsigned-only semantics
floatapproximate numericreal / double precisionfloat / doubleREALreal / floatapproximate, not exact decimal
decimalexact base-10 numericnumeric / decimaldecimal / numericcommonly NUMERIC, TEXT, or app-level decimaldecimal / numericSQLite has no fixed-precision decimal storage class
stringtexttext / varcharchar / varchar / textTEXTnvarchar / varchar / nchar / charcanonical TTOON form is UTF-8 text
datecalendar datedatedatecommonly TEXT (YYYY-MM-DD)dateSQLite is convention-based here
timewall-clock timetimetimecommonly TEXT (HH:MM:SS[.ffffff])timeno date component
datetimetimestamp / date-timetimestamp / timestamptzdatetime / timestampcommonly ISO 8601 TEXT or Unix time INTEGERdatetime2 / datetimeoffsettimezone is preserved when supported by source type
uuid128-bit identifieruuidcommonly binary(16) or char(36)commonly TEXT or BLOBuniqueidentifierMySQL and SQLite do not have a universal native UUID type
hexbinary payloadbyteabinary / varbinary / blobBLOBbinary / varbinarytext form uses hexadecimal
b64binary payloadbyteabinary / varbinary / blobBLOBbinary / varbinarytext form uses Base64

Serialization Direction

Python TypeTyped Output
Nonenull
booltrue / false
int42
float3.14
decimal.Decimal123.45m
str"Alice"
datetime.date2026-03-08
datetime.time14:30:00
datetime.datetime2026-03-08T14:30:00
uuid.UUIDuuid(550e8400-...)
byteshex(...) or b64(...)
JS ValueTyped Output
nullnull
booleantrue / false
number (safe integer)42
number (float)3.14
string"Alice"
bigint (signed i64 range)42
Date2026-03-08T14:30:00.000Z
Array[1, 2]
plain object{"name": "Alice"}
Uint8Arrayhex(...) or b64(...)
toon.decimal('123.45')123.45m
toon.uuid('...')uuid(...)
toon.date('...')2026-03-08
toon.time('14:30:00')14:30:00
toon.datetime('2026-03-08T14:30:00+08:00')2026-03-08T14:30:00+08:00

JS Date values are serialized via Date.toISOString(), so the output is UTC and includes millisecond precision.