On this page
  1. tecs.io.URI
  2. Module contents
    1. Constructors
    2. Types
    3. Functions
  3. Constructors
    1. new
  4. Types
    1. Components
  5. Functions
    1. isURI
    2. validate
    3. tecs.io.URI:authority
    4. tecs.io.URI:concatPath
    5. tecs.io.URI:fragment
    6. tecs.io.URI:host
    7. tecs.io.URI:password
    8. tecs.io.URI:path
    9. tecs.io.URI:port
    10. tecs.io.URI:query
    11. tecs.io.URI:resolve
    12. tecs.io.URI:scheme
    13. tecs.io.URI:toString
    14. tecs.io.URI:userInfo
    15. tecs.io.URI:username
    16. tecs.io.URI:withEndpoint
    17. tecs.io.URI:withFragment
    18. tecs.io.URI:withHost
    19. tecs.io.URI:withPath
    20. tecs.io.URI:withPort
    21. tecs.io.URI:withQuery
    22. tecs.io.URI:withScheme
    23. tecs.io.URI:withUserInfo

tecs.io.URI

Immutable absolute URIs for protocols, resources, and application links.

URI is not tied to HTTP. It accepts every absolute scheme supported by the native URL parser, while an API such as the HTTP client separately restricts the schemes it can use. Components are parsed once and copied into Lua, so accessors do not reparse or allocate:

local endpoint <const> = tecs.io.URI.new("https://api.example.com/v1")
local scores <const> = endpoint:concatPath("scores"):withQuery(
    "limit=20"
)

print(scores:scheme(), scores:host(), scores:path())
print(scores)

URI values are immutable. Every with method and concatPath returns a new value and leaves its receiver unchanged. Supplying a component record to tecs.io.URI.new constructs the complete initial value without intermediate copies. A modifier clones the retained parsed value and validates only the replacement component; supplying the existing value returns the receiver. withEndpoint replaces the scheme, user information, host, and port from another URI, prefixes the receiver's path with the endpoint path, and preserves the receiver's query and fragment. That makes a configured service endpoint composable with a modeled resource URI without rebuilding either from strings.

resolve applies an RFC-style relative reference to the receiver. The constructor itself requires an absolute URI, which keeps every stored value self-contained and leaves relative text at the operation where its base is known. A URI owns only immutable Lua strings and needs no close.

Module contents

Constructors

Constructor Description
new Parses and normalizes an absolute URI.

Types

Type Kind Description
Components record Components constructs one URI without intermediate immutable copies.

Functions

Function Kind Description
isURI Static Returns whether a value is a Tecs URI.
validate Static Validates an absolute URI without retaining a value.
authority Instance Returns the encoded authority.
concatPath Instance Appends a path while preserving one separator at the boundary.
fragment Instance Returns the encoded fragment without its hash.
host Instance Returns the normalized host.
password Instance Returns the encoded password.
path Instance Returns the encoded path.
port Instance Returns the explicit port.
query Instance Returns the encoded query without its question mark.
resolve Instance Resolves a relative or absolute URI reference.
scheme Instance Returns the lower-cased scheme without its colon.
toString Instance Returns the normalized absolute URI.
userInfo Instance Returns the encoded user information.
username Instance Returns the encoded username.
withEndpoint Instance Applies another URI as this resource's endpoint.
withFragment Instance Replaces or removes the fragment and returns a new URI.
withHost Instance Replaces or removes the host and returns a new URI.
withPath Instance Replaces the path and returns a new URI.
withPort Instance Replaces or removes the explicit port and returns a new URI.
withQuery Instance Replaces or removes the query and returns a new URI.
withScheme Instance Replaces the scheme and returns a new URI.
withUserInfo Instance Replaces or removes user information and returns a new URI.

Constructors

tecs.io.URI.new Static

Parses and normalizes an absolute URI. A component record performs one construction; it does not allocate an intermediate URI for each component.

function tecs.io.URI.new(
    value: string | Components
): URI, string

Arguments

Name Type Description
value string | Components The caller supplies absolute UTF-8 text or URI components.

Returns

Type Description
URI Returns an immutable URI, or nil when the text is invalid or relative.
string Returns the parser's reason when the first return is nil.

Examples

local endpoint, reason = tecs.io.URI.new(
    "https://user@example.com:8443/assets/list.json?page=2"
)
if endpoint == nil then
    error(reason)
end

assert(endpoint:scheme() == "https")
assert(endpoint:host() == "example.com")
assert(endpoint:port() == 8443)
assert(endpoint:path() == "/assets/list.json")
assert(endpoint:query() == "page=2")

Types

tecs.io.URI.Components record

Components constructs one URI without intermediate immutable copies.

record tecs.io.URI.Components
    scheme: string
    userInfo: string
    host: string
    port: integer
    path: string
    query: string
    fragment: string
end

Examples

local endpoint, reason = tecs.io.URI.new({
    scheme = "https",
    userInfo = "builder:secret",
    host = "api.example.com",
    port = 8443,
    path = "/v2/scores",
    query = "limit=20",
})
if endpoint == nil then
    error(reason)
end

assert(
    endpoint:toString(
    ) == "https://builder:secret@api.example.com:8443/v2/scores?limit=20"
)

tecs.io.URI.Components.scheme field

Caller-writable. Supplies the required scheme without its colon.

tecs.io.URI.Components.scheme: string

tecs.io.URI.Components.userInfo field

Caller-writable. Supplies encoded username or username:password, or nil for none.

tecs.io.URI.Components.userInfo: string

tecs.io.URI.Components.host field

Caller-writable. Supplies the host, or nil for a scheme without an authority. IPv6 literals may include or omit brackets.

tecs.io.URI.Components.host: string

tecs.io.URI.Components.port field

Caller-writable. Supplies the explicit port, or nil for none.

tecs.io.URI.Components.port: integer

tecs.io.URI.Components.path field

Caller-writable. Supplies the path. Nil means an empty path.

tecs.io.URI.Components.path: string

tecs.io.URI.Components.query field

Caller-writable. Supplies the query without ?, or nil for none.

tecs.io.URI.Components.query: string

tecs.io.URI.Components.fragment field

Caller-writable. Supplies the fragment without #, or nil for none.

tecs.io.URI.Components.fragment: string

Functions

tecs.io.URI.isURI Static

Returns whether a value is a Tecs URI.

function tecs.io.URI.isURI(value: any): boolean

Arguments

Name Type Description
value any The caller supplies any Lua value.

Returns

Type Description
boolean Returns true only for values created by this module.

tecs.io.URI.validate Static

Validates an absolute URI without retaining a value.

function tecs.io.URI.validate(text: string): boolean, string

Arguments

Name Type Description
text string The caller supplies the UTF-8 text to validate.

Returns

Type Description
boolean Returns true when new can parse the text.
string Returns the parser's reason when the first return is false.

Examples

local valid <const> = tecs.io.URI.validate("urn:tecs:asset:sprite")
local relative <const>, reason = tecs.io.URI.validate("../sprite.png")

assert(valid)
assert(not relative)
assert(reason ~= nil)

tecs.io.URI:authority Instance

Returns the encoded authority.

function tecs.io.URI.authority(self): string

Arguments

Name Type Description
self URI The immutable URI to inspect.

Returns

Type Description
string Returns user information, host, and port, or nil when this URI has no authority.

tecs.io.URI:concatPath Instance

Appends a path while preserving one separator at the boundary.

function tecs.io.URI.concatPath(self, path: string): URI

Arguments

Name Type Description
self URI The URI left unchanged.
path string The caller supplies the path suffix to append.

Returns

Type Description
URI Returns a new immutable URI.

Examples

local api, reason = tecs.io.URI.new("https://example.com/v1/")
if api == nil then
    error(reason)
end
local manifest <const> = api:concatPath("/games/42/manifest.json")

assert(manifest:path() == "/v1/games/42/manifest.json")

tecs.io.URI:fragment Instance

Returns the encoded fragment without its hash.

function tecs.io.URI.fragment(self): string

Arguments

Name Type Description
self URI The immutable URI to inspect.

Returns

Type Description
string Returns the fragment, or nil when the URI omits it.

tecs.io.URI:host Instance

Returns the normalized host.

function tecs.io.URI.host(self): string

Arguments

Name Type Description
self URI The immutable URI to inspect.

Returns

Type Description
string Returns the host, or nil when this scheme has none.

tecs.io.URI:password Instance

Returns the encoded password.

function tecs.io.URI.password(self): string

Arguments

Name Type Description
self URI The immutable URI to inspect.

Returns

Type Description
string Returns the password, or nil when none was supplied.

tecs.io.URI:path Instance

Returns the encoded path.

function tecs.io.URI.path(self): string

Arguments

Name Type Description
self URI The immutable URI to inspect.

Returns

Type Description
string Returns the path, including its leading slash when present.

tecs.io.URI:port Instance

Returns the explicit port.

function tecs.io.URI.port(self): integer

Arguments

Name Type Description
self URI The immutable URI to inspect.

Returns

Type Description
integer Returns the explicit port, or nil when the URI omits it.

tecs.io.URI:query Instance

Returns the encoded query without its question mark.

function tecs.io.URI.query(self): string

Arguments

Name Type Description
self URI The immutable URI to inspect.

Returns

Type Description
string Returns the query, or nil when the URI omits it.

tecs.io.URI:resolve Instance

Resolves a relative or absolute URI reference.

function tecs.io.URI.resolve(self, reference: string): URI, string

Arguments

Name Type Description
self URI The absolute base URI left unchanged.
reference string The caller supplies an RFC-style URI reference.

Returns

Type Description
URI Returns the resolved immutable URI.
string Returns the parser's reason when the reference is invalid.

Examples

local page, reason = tecs.io.URI.new(
    "https://example.com/games/current/"
)
if page == nil then
    error(reason)
end
local scores, resolveReason = page:resolve("../42/scores")
if scores == nil then
    error(resolveReason)
end

assert(scores:toString() == "https://example.com/games/42/scores")

tecs.io.URI:scheme Instance

Returns the lower-cased scheme without its colon.

function tecs.io.URI.scheme(self): string

Arguments

Name Type Description
self URI The immutable URI to inspect.

Returns

Type Description
string Returns the required scheme.

tecs.io.URI:toString Instance

Returns the normalized absolute URI.

tostring(uri) returns the same string.

function tecs.io.URI.toString(self): string

Arguments

Name Type Description
self URI The immutable URI to render.

Returns

Type Description
string Returns the complete normalized URI.

tecs.io.URI:userInfo Instance

Returns the encoded user information.

function tecs.io.URI.userInfo(self): string

Arguments

Name Type Description
self URI The immutable URI to inspect.

Returns

Type Description
string Returns username, username:password, or nil when neither was supplied.

tecs.io.URI:username Instance

Returns the encoded username.

function tecs.io.URI.username(self): string

Arguments

Name Type Description
self URI The immutable URI to inspect.

Returns

Type Description
string Returns the username, or an empty string when none was supplied.

tecs.io.URI:withEndpoint Instance

Applies another URI as this resource's endpoint.

The endpoint supplies scheme, user information, host, and port. Its path prefixes this URI's path; this URI retains its query and fragment.

function tecs.io.URI.withEndpoint(self, endpoint: URI): URI

Arguments

Name Type Description
self URI The resource URI left unchanged.
endpoint URI The caller supplies the service endpoint.

Returns

Type Description
URI Returns a new immutable URI.

Examples

local resource, resourceReason = tecs.io.URI.new(
    "smithy:/games/42/scores?limit=10"
)
if resource == nil then
    error(resourceReason)
end
local endpoint, endpointReason = tecs.io.URI.new(
    "https://api.example.com/v2"
)
if endpoint == nil then
    error(endpointReason)
end
local request <const> = resource:withEndpoint(endpoint)

assert(
    request:toString(
    ) == "https://api.example.com/v2/games/42/scores?limit=10"
)

tecs.io.URI:withFragment Instance

Replaces or removes the fragment and returns a new URI.

function tecs.io.URI.withFragment(self, fragment: string): URI

Arguments

Name Type Description
self URI The URI left unchanged.
fragment string The caller supplies a fragment without #, or nil to remove it.

Returns

Type Description
URI Returns a new immutable URI.

tecs.io.URI:withHost Instance

Replaces or removes the host and returns a new URI.

function tecs.io.URI.withHost(self, host: string): URI

Arguments

Name Type Description
self URI The URI left unchanged.
host string The caller supplies a host, or nil when the scheme permits no host.

Returns

Type Description
URI Returns a new immutable URI.

tecs.io.URI:withPath Instance

Replaces the path and returns a new URI.

function tecs.io.URI.withPath(self, path: string): URI

Arguments

Name Type Description
self URI The URI left unchanged.
path string The caller supplies an encoded or unencoded path.

Returns

Type Description
URI Returns a new immutable URI with a normalized path.

tecs.io.URI:withPort Instance

Replaces or removes the explicit port and returns a new URI.

function tecs.io.URI.withPort(self, port: integer): URI

Arguments

Name Type Description
self URI The URI left unchanged.
port integer The caller supplies a port from zero through 65535, or nil to omit it.

Returns

Type Description
URI Returns a new immutable URI.

tecs.io.URI:withQuery Instance

Replaces or removes the query and returns a new URI.

function tecs.io.URI.withQuery(self, query: string): URI

Arguments

Name Type Description
self URI The URI left unchanged.
query string The caller supplies a query without ?, or nil to remove it.

Returns

Type Description
URI Returns a new immutable URI.

Examples

local scores, reason = tecs.io.URI.new("https://example.com/scores")
if scores == nil then
    error(reason)
end
local firstPage <const> = scores:withQuery("limit=20&offset=0")

assert(scores:query() == nil)
assert(firstPage:query() == "limit=20&offset=0")

tecs.io.URI:withScheme Instance

Replaces the scheme and returns a new URI.

function tecs.io.URI.withScheme(self, scheme: string): URI

Arguments

Name Type Description
self URI The URI left unchanged.
scheme string The caller supplies a scheme without its colon.

Returns

Type Description
URI Returns a new immutable URI.

tecs.io.URI:withUserInfo Instance

Replaces or removes user information and returns a new URI.

function tecs.io.URI.withUserInfo(self, userInfo: string): URI

Arguments

Name Type Description
self URI The URI left unchanged.
userInfo string The caller supplies username, username:password, or nil to remove both components.

Returns

Type Description
URI Returns a new immutable URI.