OxL Reference

3.6 Aliases, new types and refined types

oxl
type Bytes2 = [u8; 2]                     // alias, the same type
type UserId = distinct u64                // a new type, no implicit conversions
type Port   = u16 where 1..=65535         // refined type
type Name   = str where len(1..=64)
type Email  = str where matches(re".+@.+\..+")
  • distinct T creates a new nominal type with the representation of T. Constructor UserId(5), extraction id.raw. Operators and methods of T are not inherited unless @derive(...) is declared.
  • A refined type T where P is a distinct type with the invariant P (a comptime expression over self or the shorthands len(range), matches(re), a range a..=b).
  • Obtaining a value of a refined type: (1) a literal constant — checked at compile time; (2) Port.from(x) → Port | InvalidValue; (3) deserialisation — checked automatically (§9.4); (4) Port.unchecked(x) — only in unsafe.
  • A refinement directly in a field (name: str where len(1..=64)) declares an anonymous refined type with the same rules.
  • A value of a refined type is implicitly converted to the base type (Port → u16), not the other way round.

refinement-violated

See also

Source: docs/spec/oxl-standard.en.md