Skip to main content

TealResolver

Struct TealResolver 

Source
pub struct TealResolver { /* private fields */ }
Expand description

Resolves require("a.b") to a/b.tl, a/b/init.tl, or a/b.d.tl under a sandboxed root, type-checking and generating on the fly.

Implementations§

Source§

impl TealResolver

Source

pub fn new(root: impl Into<PathBuf>) -> Result<Self, InitError>

Strict sandbox (no symlinks out of root).

Sandbox that follows symlinks directly under root (linked package roots).

Source

pub fn with_sandbox( sandbox: impl SandboxedFs + 'static, root: Option<PathBuf>, ) -> Self

Custom sandbox. Pass root so the Teal checker can also see the tree when resolving requires inside .tl files (it searches package.path).

Source

pub fn with_module_separator(self, sep: char) -> Self

The character in a module name that stands for a directory boundary. . by default, as require("a.b") writes it.

It is a setting rather than a constant because the name a host registers a module under is the host’s to choose, and one that uses / or :: still has to reach a/b.tl on disk. Only the separator moves: the candidate list built from it (.tl, /init.tl, /<last>.tl, .d.tl) is the same whatever it is.

Source

pub fn expect_type(self, type_path: impl Into<String>) -> Self

Require every .tl module served here to be assignable to type_path, written as "<module>.<Type>" (e.g. "defs.Mod", where defs.tl / defs.d.tl declares Mod). A module that does not satisfy it fails at require time even if it never annotates its own return value.

What this catches is what Teal’s record assignability catches: a field of the wrong type (hp = "lots" for hp: integer). On its own it does not catch a missing field: every Teal record field is nilable, so { name = "x" } satisfies Mod with monsters absent. Add require_fields to reject that at run time, or nil-guard optional data on the host side.

Source

pub fn require_fields( self, names: impl IntoIterator<Item = impl Into<String>>, ) -> Self

With expect_type: after the type check, these fields must be present (non-nil) in the loaded module, or the require fails naming the ones that are absent.

Naming them rather than taking all of them is what lets the type grow: the fields listed here are the contract, and a field added to the record later is optional until it is added here too. A name the record does not declare is an error at the first require, not a line that quietly does nothing.

require_all_fields is the every-field form, and the static counterpart of both is require_fields in [[contract]].

Source

pub fn require_all_fields(self) -> Self

With expect_type: every field the record declares must be present (non-nil) in the loaded module. Adding a field to the record makes every module that predates it fail, which is what require_fields exists to avoid; use this where the type is settled, or where every field really is mandatory.

Source

pub fn with_checker_path(self, dir: impl Into<PathBuf>) -> Self

Let the Teal checker also search dir when resolving requires inside served modules (and the module named by expect_type). The sandbox root is always searched; add the project src/ here when defs.tl lives there.

Source

pub fn exclude_modules( self, names: impl IntoIterator<Item = impl Into<String>>, ) -> Self

Modules (by require name) served here that are not held to expect_type / require_fields: an SDK the host writes into the same dir, for instance. The module that declares the expected type is always exempt.

Source

pub fn only_module(self, name: impl Into<String>) -> Self

Hold only this module name to expect_type / require_fields; everything else served here is type-checked as usual but not against the contract.

Source

pub fn for_contract( root: &Path, cfg: &HtlConfig, c: &Resolved, ) -> Result<Vec<Self>, InitError>

Resolvers for one [[contract]] of htl.toml: one per concrete contract dir (a dir with * expands to every subdirectory), each with expect_type(type) and the contract’s require_fields as written, its exclude / module, and the project’s search paths visible to the checker (search_paths: root, its src/ and types/, then [check] paths). root is the directory holding htl.toml. The contract-unenforced lint of htl check recognises this call.

Source

pub fn for_contract_dir( root: &Path, dir: &Path, cfg: &HtlConfig, c: &Resolved, ) -> Result<Self, InitError>

One resolver for the concrete contract directory dir (see for_contract).

Trait Implementations§

Source§

impl Resolver for TealResolver

Source§

fn resolve(&self, lua: &Lua, name: &str) -> Option<Result<Value>>

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> MaybeSend for T

Source§

impl<T> MaybeSync for T

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.