1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//! Built-in escapers.
//!
//! # Build your own escaper
//!
//! To build your own escaper,
//! make an enum with variants matching the escaper names you'd like to use,
//! and have it implement [`oxiplate_traits::Escaper`].
//! Oxiplate templates usually use `snake_case` escaper names,
//! so it's suggested to use those on your escaper group enum.
//!
//! ```rust
//! use std::fmt::{Result, Write};
//!
//! use oxiplate_traits::Escaper;
//!
//! # #[allow(dead_code)]
//! #[allow(non_camel_case_types)]
//! pub enum YourEscaper {
//! # #[allow(dead_code)]
//! foo,
//! # #[allow(dead_code)]
//! bar,
//! }
//!
//! impl Escaper for YourEscaper {
//! const DEFAULT: Self = Self::foo;
//!
//! #[inline]
//! fn escape<W: Write + ?Sized>(&self, f: &mut W, value: &str) -> Result {
//! match self {
//! Self::foo => escape_foo(f, value),
//! Self::bar => bar_escaper(f, value),
//! }
//! }
//! }
//!
//! # #[allow(dead_code)]
//! #[inline]
//! fn escape_foo<W: Write + ?Sized>(f: &mut W, value: &'_ str) -> Result {
//! if !value.contains("foo") {
//! return f.write_str(value);
//! }
//!
//! f.write_str(&value.replace("foo", "f00"))
//! }
//!
//! # #[allow(dead_code)]
//! #[inline]
//! fn bar_escaper<W: Write + ?Sized>(f: &mut W, value: &'_ str) -> Result {
//! if !value.contains("bar") {
//! return f.write_str(value);
//! }
//!
//! f.write_str(&value.replace("bar", "b@r"))
//! }
//! ```
//!
//! ## TOML config
//!
//! ```toml
//! [escaper_groups.your_group]
//! escaper = "::your_crate::YourEscaper"
//! ```
//!
//! ## Rust code
//!
//! ```
//! use oxiplate::{Oxiplate, Render};
//!
//! #[derive(Oxiplate)]
//! // Because the TOML isn't included in this,
//! // `your_group` isn't available and the example doesn't compile.
//! #[oxiplate_inline(your_group: "{{ foo: value_to_escape }} | {{ bar: value_to_escape }}")]
//! struct Data<'a> {
//! value_to_escape: &'a str,
//! }
//!
//! let data = Data {
//! value_to_escape: "foo bar",
//! };
//!
//! assert_eq!(data.render()?, r#"f00 bar | foo b@r"#);
//!
//! # Ok::<(), ::core::fmt::Error>(())
//! ```