pub struct Engine { /* private fields */ }Expand description
Renders templates and loads documents. See the module documentation.
Engine is a cheap handle: clones share the same base scope, loaders and
cache. It is single-threaded (not Send).
Implementations§
Source§impl Engine
impl Engine
Sourcepub fn new(spawner: Option<SpawnFn>) -> Self
pub fn new(spawner: Option<SpawnFn>) -> Self
Creates an engine with no loaders and an empty cache.
Imports run as background tasks. spawner hands those tasks to the
host’s async runtime (for example tokio::task::spawn_local, or
wasm_bindgen_futures::spawn_local). With None, tasks go onto a
thread-local queue, and the host must call
helpers::run_pending to run them.
Sourcepub fn add_builtin(&self, name: &str, value: Value)
pub fn add_builtin(&self, name: &str, value: Value)
Binds name to value in the base scope.
The name is visible in every scope and document of this engine,
including those created earlier, unless a template shadows it. Use it to
pass data and host functions (Value::Builtin) to templates.
Sourcepub fn add_loader(&self, protocol: &str, loader: LoaderFn)
pub fn add_loader(&self, protocol: &str, loader: LoaderFn)
Registers loader for the URIs whose scheme is protocol (for example
"https" or "file", without the colon). The scheme is
case-insensitive. A later call for the same scheme replaces the loader.
Sourcepub fn add_default_loader(&self, loader: LoaderFn)
pub fn add_default_loader(&self, loader: LoaderFn)
Registers the loader for URIs without a scheme, such as /dir/doc.texl
or doc.texl. A later call replaces it.
Sourcepub async fn load(&self, uri: &str) -> Value
pub async fn load(&self, uri: &str) -> Value
Loads and renders the document at uri.
The URI is normalized (a scheme-less path becomes absolute, so doc.texl
is /doc.texl), then passed to the loader of its scheme, or to the
default loader if it has none. The source is rendered in a fresh child of
the base scope, and imports inside it resolve against the URI.
This method always loads the document, but it stores the result in the cache, so later imports of the same URI reuse it.
§Returns
- The document namespace
{uri, source, data, rendering}(see the module documentation). Nothingif no loader matches the URI or the loader fails.Undefinedif the URI cannot be normalized.
§Examples
use swan_core::value::Value;
use texl_core::{Engine, loader_fn};
let engine = Engine::new(None);
engine.add_loader("mem", loader_fn(|_uri| async { Ok("<% x = 1 %>x is <% x %>".to_string()) }));
let Value::Namespace(doc) = block_on(engine.load("mem://doc")) else { panic!() };
assert_eq!(doc.get("rendering"), Value::Text("x is 1".into()));
assert_eq!(doc.get("uri"), Value::Text("mem://doc".into()));Sourcepub async fn render(&self, template: &str) -> String
pub async fn render(&self, template: &str) -> String
Renders template in a fresh scope (see Engine::create_scope) and
returns the rendered text.
Names assigned by the template are discarded afterwards. To keep them,
create a scope and call template::render directly.
§Examples
use texl_core::Engine;
let engine = Engine::new(None);
assert_eq!(block_on(engine.render("1 + 1 = <% 1 + 1 %>")), "1 + 1 = 2");Sourcepub fn create_scope(&self, base_url: Option<String>) -> Scope
pub fn create_scope(&self, base_url: Option<String>) -> Scope
Creates a new child of the base scope with its own texl namespace.
base_url is the URI of the document the scope stands for: texl.import
resolves relative URIs against it, as in a document loaded with
Engine::load. It is normalized first, so docs/main.texl is
/docs/main.texl. With None, the scope has no document and relative
URIs resolve against the root path /.
Use it to render a document whose source the host already has, or to
render several templates in the same scope with template::render and
share names between them. The scope is not a loaded document: nothing is
loaded or cached for base_url.
§Examples
use texl_core::{Engine, loader_fn, template};
let engine = Engine::new(None);
engine.add_default_loader(loader_fn(|uri| async move {
match uri.as_str() {
"/docs/name.texl" => Ok("Ada".to_string()),
_ => Err(format!("{uri}: not found")),
}
}));
let scope = engine.create_scope(Some("docs/main.texl".to_string()));
let source = r#"Hello <% texl.import("name.texl") ~> (doc -> doc.rendering) %>!"#;
assert_eq!(block_on(template::render(source, &scope)), "Hello Ada!");