summaryrefslogtreecommitdiffstats
path: root/vendor/handlebars/src/lib.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /vendor/handlebars/src/lib.rs
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/handlebars/src/lib.rs')
-rw-r--r--vendor/handlebars/src/lib.rs417
1 files changed, 417 insertions, 0 deletions
diff --git a/vendor/handlebars/src/lib.rs b/vendor/handlebars/src/lib.rs
new file mode 100644
index 000000000..7e0aac830
--- /dev/null
+++ b/vendor/handlebars/src/lib.rs
@@ -0,0 +1,417 @@
+#![doc(html_root_url = "https://docs.rs/handlebars/4.1.0")]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+//! # Handlebars
+//!
+//! [Handlebars](http://handlebarsjs.com/) is a modern and extensible templating solution originally created in the JavaScript world. It's used by many popular frameworks like [Ember.js](http://emberjs.com) and Chaplin. It's also ported to some other platforms such as [Java](https://github.com/jknack/handlebars.java).
+//!
+//! And this is handlebars Rust implementation, designed for general purpose text generation.
+//!
+//! ## Quick Start
+//!
+//! ```
+//! use std::collections::BTreeMap;
+//! use handlebars::Handlebars;
+//!
+//! fn main() {
+//! // create the handlebars registry
+//! let mut handlebars = Handlebars::new();
+//!
+//! // register the template. The template string will be verified and compiled.
+//! let source = "hello {{world}}";
+//! assert!(handlebars.register_template_string("t1", source).is_ok());
+//!
+//! // Prepare some data.
+//! //
+//! // The data type should implements `serde::Serialize`
+//! let mut data = BTreeMap::new();
+//! data.insert("world".to_string(), "世界!".to_string());
+//! assert_eq!(handlebars.render("t1", &data).unwrap(), "hello 世界!");
+//! }
+//! ```
+//!
+//! In this example, we created a template registry and registered a template named `t1`.
+//! Then we rendered a `BTreeMap` with an entry of key `world`, the result is just what
+//! we expected.
+//!
+//! I recommend you to walk through handlebars.js' [intro page](http://handlebarsjs.com)
+//! if you are not quite familiar with the template language itself.
+//!
+//! ## Features
+//!
+//! Handlebars is a real-world templating system that you can use to build
+//! your application without pain.
+//!
+//! ### Isolation of Rust and HTML
+//!
+//! This library doesn't attempt to use some macro magic to allow you to
+//! write your template within your rust code. I admit that it's fun to do
+//! that but it doesn't fit real-world use cases.
+//!
+//! ### Limited but essential control structures built-in
+//!
+//! Only essential control directives `if` and `each` are built-in. This
+//! prevents you from putting too much application logic into your template.
+//!
+//! ### Extensible helper system
+//!
+//! Helper is the control system of handlebars language. In the original JavaScript
+//! version, you can implement your own helper with JavaScript.
+//!
+//! Handlebars-rust offers similar mechanism that custom helper can be defined with
+//! rust function, or [rhai](https://github.com/jonathandturner/rhai) script.
+//!
+//! The built-in helpers like `if` and `each` were written with these
+//! helper APIs and the APIs are fully available to developers.
+//!
+//! ### Auto-reload in dev mode
+//!
+//! By turning on `dev_mode`, handlebars auto reloads any template and scripts that
+//! loaded from files or directory. This can be handy for template development.
+//!
+//! ### Template inheritance
+//!
+//! Every time I look into a templating system, I will investigate its
+//! support for [template inheritance][t].
+//!
+//! [t]: https://docs.djangoproject.com/en/1.9/ref/templates/language/#template-inheritance
+//!
+//! Template include is not sufficient for template reuse. In most cases
+//! you will need a skeleton of page as parent (header, footer, etc.), and
+//! embed your page into this parent.
+//!
+//! You can find a real example of template inheritance in
+//! `examples/partials.rs` and templates used by this file.
+//!
+//! ### Strict mode
+//!
+//! Handlebars, the language designed to work with JavaScript, has no
+//! strict restriction on accessing nonexistent fields or indexes. It
+//! generates empty strings for such cases. However, in Rust we want to be
+//! a little stricter sometimes.
+//!
+//! By enabling `strict_mode` on handlebars:
+//!
+//! ```
+//! # use handlebars::Handlebars;
+//! # let mut handlebars = Handlebars::new();
+//! handlebars.set_strict_mode(true);
+//! ```
+//!
+//! You will get a `RenderError` when accessing fields that do not exist.
+//!
+//! ## Limitations
+//!
+//! ### Compatibility with original JavaScript version
+//!
+//! This implementation is **not fully compatible** with the original JavaScript version.
+//!
+//! First of all, mustache blocks are not supported. I suggest you to use `#if` and `#each` for
+//! the same functionality.
+//!
+//! There are some other minor features missing:
+//!
+//! * Chained else [#12](https://github.com/sunng87/handlebars-rust/issues/12)
+//!
+//! Feel free to file an issue on [github](https://github.com/sunng87/handlebars-rust/issues) if
+//! you find missing features.
+//!
+//! ### Types
+//!
+//! As a static typed language, it's a little verbose to use handlebars.
+//! Handlebars templating language is designed against JSON data type. In rust,
+//! we will convert user's structs, vectors or maps into Serde-Json's `Value` type
+//! in order to use in templates. You have to make sure your data implements the
+//! `Serialize` trait from the [Serde](https://serde.rs) project.
+//!
+//! ## Usage
+//!
+//! ### Template Creation and Registration
+//!
+//! Templates are created from `String`s and registered to `Handlebars` with a name.
+//!
+//! ```
+//! # extern crate handlebars;
+//!
+//! use handlebars::Handlebars;
+//!
+//! # fn main() {
+//! let mut handlebars = Handlebars::new();
+//! let source = "hello {{world}}";
+//!
+//! assert!(handlebars.register_template_string("t1", source).is_ok())
+//! # }
+//! ```
+//!
+//! On registration, the template is parsed, compiled and cached in the registry. So further
+//! usage will benefit from the one-time work. Also features like include, inheritance
+//! that involves template reference requires you to register those template first with
+//! a name so the registry can find it.
+//!
+//! If you template is small or just to experiment, you can use `render_template` API
+//! without registration.
+//!
+//! ```
+//! # use std::error::Error;
+//! use handlebars::Handlebars;
+//! use std::collections::BTreeMap;
+//!
+//! # fn main() -> Result<(), Box<Error>> {
+//! let mut handlebars = Handlebars::new();
+//! let source = "hello {{world}}";
+//!
+//! let mut data = BTreeMap::new();
+//! data.insert("world".to_string(), "世界!".to_string());
+//! assert_eq!(handlebars.render_template(source, &data)?, "hello 世界!".to_owned());
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! ### Rendering Something
+//!
+//! Since handlebars is originally based on JavaScript type system. It supports dynamic features like duck-typing, truthy/falsey values. But for a static language like Rust, this is a little difficult. As a solution, we are using the `serde_json::value::Value` internally for data rendering.
+//!
+//! That means, if you want to render something, you have to ensure the data type implements the `serde::Serialize` trait. Most rust internal types already have that trait. Use `#derive[Serialize]` for your types to generate default implementation.
+//!
+//! You can use default `render` function to render a template into `String`. From 0.9, there's `render_to_write` to render text into anything of `std::io::Write`.
+//!
+//! ```
+//! # use std::error::Error;
+//! # #[macro_use]
+//! # extern crate serde_derive;
+//! # extern crate handlebars;
+//!
+//! use handlebars::Handlebars;
+//!
+//! #[derive(Serialize)]
+//! struct Person {
+//! name: String,
+//! age: i16,
+//! }
+//!
+//! # fn main() -> Result<(), Box<Error>> {
+//! let source = "Hello, {{name}}";
+//!
+//! let mut handlebars = Handlebars::new();
+//! assert!(handlebars.register_template_string("hello", source).is_ok());
+//!
+//!
+//! let data = Person {
+//! name: "Ning Sun".to_string(),
+//! age: 27
+//! };
+//! assert_eq!(handlebars.render("hello", &data)?, "Hello, Ning Sun".to_owned());
+//! # Ok(())
+//! # }
+//! #
+//! ```
+//!
+//! Or if you don't need the template to be cached or referenced by other ones, you can
+//! simply render it without registering.
+//!
+//! ```
+//! # use std::error::Error;
+//! # #[macro_use]
+//! # extern crate serde_derive;
+//! # extern crate handlebars;
+//! use handlebars::Handlebars;
+//! # #[derive(Serialize)]
+//! # struct Person {
+//! # name: String,
+//! # age: i16,
+//! # }
+//!
+//! # fn main() -> Result<(), Box<dyn Error>> {
+//! let source = "Hello, {{name}}";
+//!
+//! let mut handlebars = Handlebars::new();
+//!
+//! let data = Person {
+//! name: "Ning Sun".to_string(),
+//! age: 27
+//! };
+//! assert_eq!(handlebars.render_template("Hello, {{name}}", &data)?,
+//! "Hello, Ning Sun".to_owned());
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! #### Escaping
+//!
+//! As per the handlebars spec, output using `{{expression}}` is escaped by default (to be precise, the characters `&"<>` are replaced by their respective html / xml entities). However, since the use cases of a rust template engine are probably a bit more diverse than those of a JavaScript one, this implementation allows the user to supply a custom escape function to be used instead. For more information see the `EscapeFn` type and `Handlebars::register_escape_fn()` method. In particular, `no_escape()` can be used as the escape function if no escaping at all should be performed.
+//!
+//! ### Custom Helper
+//!
+//! Handlebars is nothing without helpers. You can also create your own helpers with rust. Helpers in handlebars-rust are custom struct implements the `HelperDef` trait, concretely, the `call` function. For your convenience, most of stateless helpers can be implemented as bare functions.
+//!
+//! ```
+//! use std::io::Write;
+//! # use std::error::Error;
+//! use handlebars::{Handlebars, HelperDef, RenderContext, Helper, Context, JsonRender, HelperResult, Output, RenderError};
+//!
+//! // implement by a structure impls HelperDef
+//! #[derive(Clone, Copy)]
+//! struct SimpleHelper;
+//!
+//! impl HelperDef for SimpleHelper {
+//! fn call<'reg: 'rc, 'rc>(&self, h: &Helper, _: &Handlebars, _: &Context, rc: &mut RenderContext, out: &mut dyn Output) -> HelperResult {
+//! let param = h.param(0).unwrap();
+//!
+//! out.write("1st helper: ")?;
+//! out.write(param.value().render().as_ref())?;
+//! Ok(())
+//! }
+//! }
+//!
+//! // implement via bare function
+//! fn another_simple_helper (h: &Helper, _: &Handlebars, _: &Context, rc: &mut RenderContext, out: &mut dyn Output) -> HelperResult {
+//! let param = h.param(0).unwrap();
+//!
+//! out.write("2nd helper: ")?;
+//! out.write(param.value().render().as_ref())?;
+//! Ok(())
+//! }
+//!
+//!
+//! # fn main() -> Result<(), Box<dyn Error>> {
+//! let mut handlebars = Handlebars::new();
+//! handlebars.register_helper("simple-helper", Box::new(SimpleHelper));
+//! handlebars.register_helper("another-simple-helper", Box::new(another_simple_helper));
+//! // via closure
+//! handlebars.register_helper("closure-helper",
+//! Box::new(|h: &Helper, r: &Handlebars, _: &Context, rc: &mut RenderContext, out: &mut dyn Output| -> HelperResult {
+//! let param = h.param(0).ok_or(RenderError::new("param not found"))?;
+//!
+//! out.write("3rd helper: ")?;
+//! out.write(param.value().render().as_ref())?;
+//! Ok(())
+//! }));
+//!
+//! let tpl = "{{simple-helper 1}}\n{{another-simple-helper 2}}\n{{closure-helper 3}}";
+//! assert_eq!(handlebars.render_template(tpl, &())?,
+//! "1st helper: 1\n2nd helper: 2\n3rd helper: 3".to_owned());
+//! # Ok(())
+//! # }
+//!
+//! ```
+//!
+//! Data available to helper can be found in [Helper](struct.Helper.html). And there are more
+//! examples in [HelperDef](trait.HelperDef.html) page.
+//!
+//! You can learn more about helpers by looking into source code of built-in helpers.
+//!
+//!
+//! ### Script Helper
+//!
+//! Like our JavaScript counterparts, handlebars allows user to define simple helpers with
+//! a scripting language, [rhai](https://docs.rs/crate/rhai/). This can be enabled by
+//! turning on `script_helper` feature flag.
+//!
+//! A sample script:
+//!
+//! ```handlebars
+//! {{percent 0.34 label="%"}}
+//! ```
+//!
+//! ```rhai
+//! // percent.rhai
+//! // get first parameter from `params` array
+//! let value = params[0];
+//! // get key value pair `label` from `hash` map
+//! let label = hash["label"];
+//!
+//! // compute the final string presentation
+//! (value * 100).to_string() + label
+//! ```
+//!
+//! A runnable [example](https://github.com/sunng87/handlebars-rust/blob/master/examples/script.rs) can be find in the repo.
+//!
+//! #### Built-in Helpers
+//!
+//! * `{{{{raw}}}} ... {{{{/raw}}}}` escape handlebars expression within the block
+//! * `{{#if ...}} ... {{else}} ... {{/if}}` if-else block
+//! (See [the handlebarjs documentation](https://handlebarsjs.com/guide/builtin-helpers.html#if) on how to use this helper.)
+//! * `{{#unless ...}} ... {{else}} .. {{/unless}}` if-not-else block
+//! (See [the handlebarjs documentation](https://handlebarsjs.com/guide/builtin-helpers.html#unless) on how to use this helper.)
+//! * `{{#each ...}} ... {{/each}}` iterates over an array or object. Handlebars-rust doesn't support mustache iteration syntax so use `each` instead.
+//! (See [the handlebarjs documentation](https://handlebarsjs.com/guide/builtin-helpers.html#each) on how to use this helper.)
+//! * `{{#with ...}} ... {{/with}}` change current context. Similar to `{{#each}}`, used for replace corresponding mustache syntax.
+//! (See [the handlebarjs documentation](https://handlebarsjs.com/guide/builtin-helpers.html#with) on how to use this helper.)
+//! * `{{lookup ... ...}}` get value from array by `@index` or `@key`
+//! (See [the handlebarjs documentation](https://handlebarsjs.com/guide/builtin-helpers.html#lookup) on how to use this helper.)
+//! * `{{> ...}}` include template by its name
+//! * `{{log ...}}` log value with rust logger, default level: INFO. Currently you cannot change the level.
+//! * Boolean helpers that can be used in `if` as subexpression, for example `{{#if (gt 2 1)}} ...`:
+//! * `eq`
+//! * `ne`
+//! * `gt`
+//! * `gte`
+//! * `lt`
+//! * `lte`
+//! * `and`
+//! * `or`
+//! * `not`
+//! * `{{len ...}}` returns length of array/object/string
+//!
+//! ### Template inheritance
+//!
+//! Handlebars.js' partial system is fully supported in this implementation.
+//! Check [example](https://github.com/sunng87/handlebars-rust/blob/master/examples/partials.rs#L49) for details.
+//!
+//!
+
+#![allow(dead_code, clippy::upper_case_acronyms)]
+#![warn(rust_2018_idioms)]
+#![recursion_limit = "200"]
+
+#[cfg(not(feature = "no_logging"))]
+#[macro_use]
+extern crate log;
+
+#[cfg(test)]
+#[macro_use]
+extern crate maplit;
+#[macro_use]
+extern crate pest_derive;
+#[macro_use]
+extern crate quick_error;
+#[cfg(test)]
+#[macro_use]
+extern crate serde_derive;
+
+#[allow(unused_imports)]
+#[macro_use]
+extern crate serde_json;
+
+pub use self::block::{BlockContext, BlockParams};
+pub use self::context::Context;
+pub use self::decorators::DecoratorDef;
+pub use self::error::{RenderError, TemplateError};
+pub use self::helpers::{HelperDef, HelperResult};
+pub use self::json::path::Path;
+pub use self::json::value::{to_json, JsonRender, PathAndJson, ScopedJson};
+pub use self::output::{Output, StringOutput};
+pub use self::registry::{html_escape, no_escape, EscapeFn, Registry as Handlebars};
+pub use self::render::{Decorator, Evaluable, Helper, RenderContext, Renderable};
+pub use self::template::Template;
+
+#[doc(hidden)]
+pub use self::serde_json::Value as JsonValue;
+
+#[macro_use]
+mod macros;
+mod block;
+mod context;
+mod decorators;
+mod error;
+mod grammar;
+mod helpers;
+mod json;
+mod local_vars;
+mod output;
+mod partial;
+mod registry;
+mod render;
+mod sources;
+mod support;
+pub mod template;
+mod util;