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
impl TealResolver
Sourcepub fn new(root: impl Into<PathBuf>) -> Result<Self, InitError>
pub fn new(root: impl Into<PathBuf>) -> Result<Self, InitError>
Strict sandbox (no symlinks out of root).
Sourcepub fn new_symlink_aware(root: impl Into<PathBuf>) -> Result<Self, InitError>
pub fn new_symlink_aware(root: impl Into<PathBuf>) -> Result<Self, InitError>
Sandbox that follows symlinks directly under root (linked package roots).
Sourcepub fn with_sandbox(
sandbox: impl SandboxedFs + 'static,
root: Option<PathBuf>,
) -> Self
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).
pub fn with_module_separator(self, sep: char) -> Self
Sourcepub fn expect_type(self, type_path: impl Into<String>) -> Self
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.
Sourcepub fn require_fields(
self,
names: impl IntoIterator<Item = impl Into<String>>,
) -> Self
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]].
Sourcepub fn require_all_fields(self) -> Self
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.
Sourcepub fn with_checker_path(self, dir: impl Into<PathBuf>) -> Self
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.
Sourcepub fn exclude_modules(
self,
names: impl IntoIterator<Item = impl Into<String>>,
) -> Self
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.
Sourcepub fn only_module(self, name: impl Into<String>) -> Self
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.
Sourcepub fn for_contract(
root: &Path,
cfg: &HtlConfig,
c: &Resolved,
) -> Result<Vec<Self>, InitError>
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.
Sourcepub fn for_contract_dir(
root: &Path,
dir: &Path,
cfg: &HtlConfig,
c: &Resolved,
) -> Result<Self, InitError>
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§
Auto Trait Implementations§
impl !Freeze for TealResolver
impl !RefUnwindSafe for TealResolver
impl !UnwindSafe for TealResolver
impl Send for TealResolver
impl Sync for TealResolver
impl Unpin for TealResolver
impl UnsafeUnpin for TealResolver
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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