Schema Definition
TON provides built-in schema validation with path-based property specifications.
Path-Based Schema Syntax
TON uses forward slashes to specify property paths in schemas:
{(user)
name = "John",
email = "[email protected]",
details = {
bio = "Software engineer",
avatar = "avatar.jpg"
}
}
#! {(user)
/name = string(required, maxLength(100)),
/email = string(required, format(email)),
/details/bio = string(maxLength(1000)),
/details/avatar = string(maxLength(255))
}
Why Path-Based Syntax?
- Clear Hierarchy: Paths mirror the data structure
- Unambiguous: Each property has a unique path
- Familiar: Similar to file paths and URLs
- Deep Validation: Apply rules to nested properties
Schema Placement
// Schema at end of file
{(data)
// ... data ...
}
#! {(data)
// ... schema rules ...
}
// Or reference external schema
#@ @schemaFile = 'schema.ton'
Validation Rules
Universal Rules (All Types)
required
- Property must be presentnotnull
- Cannot be nulldefault(value)
- Default for missingdefaultWhenNull(value)
- Default for nulldefaultWhenEmpty(value)
- Default for emptydefaultWhenInvalid(value)
- Default on validation failure
String Validation
/name = string(minLength(1), maxLength(100))
/email = string(format(email))
/url = string(pattern("^https?://"))
/bio = string(multiline(true), maxLength(1000))
Number Validation
/age = int(min(0), max(150))
/score = float(range(0.0, 100.0))
/port = int(range(1, 65535))
/flags = int(bits(8), unsigned)
Array Validation
/tags = array:string(minCount(1), maxCount(10))
/scores = array:float(unique, sorted)
/matrix = array:array:int(maxCount(10))
Complex Example
{(company)
name = "TechCorp",
employees = 250,
headquarters = {
address = "123 Tech St",
city = "San Francisco",
coordinates = {
latitude = 37.7749,
longitude = -122.4194
}
},
2024revenue = 1500000,
departments = [
{(dept) name = "Engineering", count = 120},
{(dept) name = "Sales", count = 80}
]
}
#! {(company)
/name = string(required, maxLength(100)),
/employees = int(min(1), max(10000)),
# Nested paths
/headquarters/address = string(required),
/headquarters/city = string(required),
# Deep nested paths
/headquarters/coordinates/latitude = float(range(-90.0, 90.0)),
/headquarters/coordinates/longitude = float(range(-180.0, 180.0)),
# Numeric property paths
/2024revenue = float(positive),
# Array validation
/departments = array:object(minCount(1))
}
#! {(dept)
/name = string(required),
/count = int(positive)
}
Enum Definitions
#! enum(status) [pending, active, completed, cancelled]
#! enumSet(permissions) [read, write, delete, admin]
#! {(user)
/status = enum:status(required),
/permissions = enumSet:permissions(minCount(1))
}