Skip to content

Commit

Permalink
escape strings
Browse files Browse the repository at this point in the history
  • Loading branch information
Schniz committed Sep 21, 2019
1 parent 45d44a9 commit a6199b7
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 16 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions render/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ license = "MIT"

[dependencies]
render_macros = { path = "../render_macros", version = "0.1" }
htmlescape = "0.3"

[dev-dependencies]
pretty_assertions = "0.6"
21 changes: 11 additions & 10 deletions render/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
//! > 🔏 A safe and simple template engine with the ergonomics of JSX
//!
//!
//! The `Renderable` trait contains a simple function that returns `String`. This is very handy for type-safe HTML templates, but can also work for writing tree-like terminal coloring mechanism like ReasonML's [Pastel](https://reason-native.com/docs/pastel/).
//!
//!
//! ## Why this is different from `typed-html`?
//!
//!
//! `typed-html` is a wonderful library. Unfortunately, it focused its power in strictness of the HTML spec itself, and doesn't allow arbitrary compositions of custom elements.
//!
//!
//! `render` takes a different approach. For now, HTML is not typed at all. It can get any key and get any string value. The main focus is custom components, so you can create a composable and declarative template with no runtime errors.
//!
//!
//! ## Usage
//!
//!
//! ```rust
//! #![feature(proc_macro_hygiene)]
//!
//!
//! // A simple HTML 5 doctype declaration
//! use render::html::HTML5Doctype;
//! use render::{
Expand All @@ -23,14 +23,14 @@
//! // A trait for custom components
//! Renderable,
//! };
//!
//!
//! // This can be any layout we want
//! #[derive(Debug)]
//! struct Page<'a, T: Renderable> {
//! title: &'a str,
//! children: T,
//! }
//!
//!
//! // Implementing `Renderable` gives the ability to compose
//! // components
//! impl<'a, T: Renderable> Renderable for Page<'a, T> {
Expand All @@ -48,7 +48,7 @@
//! }
//! }
//! }
//!
//!
//! // This can be a route in Rocket, the web framework,
//! // for instance.
//! pub fn some_page(user_name: &str) -> String {
Expand Down Expand Up @@ -83,3 +83,4 @@ pub use fragment::Fragment;
pub use render_macros::{html, rsx};
pub use renderable::Renderable;
pub use simple_element::SimpleElement;
pub use text_element::Raw;
53 changes: 47 additions & 6 deletions render/src/text_element.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,58 @@
use crate::Renderable;
use htmlescape::encode_minimal;

/// Renders the string
/// > TODO: this should escape HTML!
/// Renders an escaped-html string
impl Renderable for String {
fn render(self) -> String {
self
encode_minimal(&self)
}
}

/// Renders the string
/// > TODO: this should escape HTML!
/// Renders an escaped-html string
impl Renderable for &str {
fn render(self) -> String {
self.to_string()
encode_minimal(self)
}
}

/// A raw (unencoded) html string
#[derive(Debug)]
pub struct Raw<'s>(&'s str);

impl<'s> From<&'s str> for Raw<'s> {
fn from(s: &'s str) -> Self {
Raw(s)
}
}

/// A raw (unencoded) html string
impl<'s> Renderable for Raw<'s> {
fn render(self) -> String {
self.0.to_string()
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn decodes_html() {
let rendered = "<Hello />".render();
assert_eq!(rendered, "&lt;Hello /&gt;");
}

#[test]
fn allows_raw_text() {
let rendered = Raw::from("<Hello />").render();
assert_eq!(rendered, "<Hello />");
}
}

/// Creates a raw (unencoded) html string
#[macro_export]
macro_rules! raw {
($text:expr) => {
::render::Raw::from($text)
};
}
12 changes: 12 additions & 0 deletions render_tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,15 @@ pub fn it_works() -> String {
pub fn verify_works() {
println!("{}", it_works());
}

#[test]
pub fn works_with_raw() {
use pretty_assertions::assert_eq;
use render::raw;

let actual = html! {
<div>{raw!("<Hello />")}</div>
};

assert_eq!(actual, "<div><Hello /></div>");
}

0 comments on commit a6199b7

Please sign in to comment.