You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
3.3KB

  1. use std::collections::HashMap;
  2. use base64::{encode, decode};
  3. use pulldown_cmark as cmark;
  4. use tera::{Value, to_value, Result as TeraResult};
  5. pub fn markdown(value: Value, args: HashMap<String, Value>) -> TeraResult<Value> {
  6. let s = try_get_value!("markdown", "value", String, value);
  7. let inline = match args.get("inline") {
  8. Some(val) => try_get_value!("markdown", "inline", bool, val),
  9. None => false,
  10. };
  11. let mut html = String::new();
  12. let parser = cmark::Parser::new(&s);
  13. cmark::html::push_html(&mut html, parser);
  14. if inline {
  15. html = html
  16. .trim_left_matches("<p>")
  17. // pulldown_cmark finishes a paragraph with `</p>\n`
  18. .trim_right_matches("</p>\n")
  19. .to_string();
  20. }
  21. Ok(to_value(&html).unwrap())
  22. }
  23. pub fn base64_encode(value: Value, _: HashMap<String, Value>) -> TeraResult<Value> {
  24. let s = try_get_value!("base64_encode", "value", String, value);
  25. Ok(
  26. to_value(&encode(s.as_bytes())).unwrap()
  27. )
  28. }
  29. pub fn base64_decode(value: Value, _: HashMap<String, Value>) -> TeraResult<Value> {
  30. let s = try_get_value!("base64_decode", "value", String, value);
  31. Ok(
  32. to_value(
  33. &String::from_utf8(
  34. decode(s.as_bytes()).unwrap()
  35. ).unwrap()
  36. ).unwrap()
  37. )
  38. }
  39. #[cfg(test)]
  40. mod tests {
  41. use std::collections::HashMap;
  42. use tera::to_value;
  43. use super::{markdown, base64_decode, base64_encode};
  44. #[test]
  45. fn markdown_filter() {
  46. let result = markdown(to_value(&"# Hey").unwrap(), HashMap::new());
  47. assert!(result.is_ok());
  48. assert_eq!(result.unwrap(), to_value(&"<h1>Hey</h1>\n").unwrap());
  49. }
  50. #[test]
  51. fn markdown_filter_inline() {
  52. let mut args = HashMap::new();
  53. args.insert("inline".to_string(), to_value(true).unwrap());
  54. let result = markdown(to_value(&"Using `map`, `filter`, and `fold` instead of `for`").unwrap(), args);
  55. assert!(result.is_ok());
  56. assert_eq!(result.unwrap(), to_value(&"Using <code>map</code>, <code>filter</code>, and <code>fold</code> instead of <code>for</code>").unwrap());
  57. }
  58. #[test]
  59. fn base64_encode_filter() {
  60. // from https://tools.ietf.org/html/rfc4648#section-10
  61. let tests = vec![
  62. ("", ""),
  63. ("f", "Zg=="),
  64. ("fo", "Zm8="),
  65. ("foo", "Zm9v"),
  66. ("foob", "Zm9vYg=="),
  67. ("fooba", "Zm9vYmE="),
  68. ("foobar", "Zm9vYmFy")
  69. ];
  70. for (input, expected) in tests {
  71. let args = HashMap::new();
  72. let result = base64_encode(to_value(input).unwrap(), args);
  73. assert!(result.is_ok());
  74. assert_eq!(result.unwrap(), to_value(expected).unwrap());
  75. }
  76. }
  77. #[test]
  78. fn base64_decode_filter() {
  79. let tests = vec![
  80. ("", ""),
  81. ("Zg==", "f"),
  82. ("Zm8=", "fo"),
  83. ("Zm9v", "foo"),
  84. ("Zm9vYg==", "foob"),
  85. ("Zm9vYmE=", "fooba"),
  86. ("Zm9vYmFy", "foobar")
  87. ];
  88. for (input, expected) in tests {
  89. let args = HashMap::new();
  90. let result = base64_decode(to_value(input).unwrap(), args);
  91. assert!(result.is_ok());
  92. assert_eq!(result.unwrap(), to_value(expected).unwrap());
  93. }
  94. }
  95. }