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.

filters.rs 4.3KB

Fix clippy warnings (#744) Clippy is returning some warnings. Let's fix or explicitly ignore them. In particular: - In `components/imageproc/src/lib.rs`, we implement `Hash` explicitly but derive `PartialEq`. We need to maintain the property that two keys being equal implies the hashes of those two keys are equal. Our `Hash` implementations preserve this, so we'll explicitly ignore the warnings. - In `components/site/src/lib.rs`, we were calling `.into()` on some values that are already of the correct type. - In `components/site/src/lib.rs`, we were using `.map(|x| *x)` in iterator chains to remove a level of indirection; we can instead say `.copied()` (introduced in Rust v1.36) or `.cloned()`. Using `.copied` here is better from a type-checking point of view, but we'll use `.cloned` for now as Rust v1.36 was only recently released. - In `components/templates/src/filters.rs` and `components/utils/src/site.rs`, we were taking `HashMap`s as function arguments but not generically accepting alternate `Hasher` implementations. - In `src/cmd/check.rs`, we use `env::current_dir()` as a default value, but our use of `unwrap_or` meant that we would always retrieve the current directory even when not needed. - In `components/errors/src/lib.rs`, we can use `if let` rather than `match`. - In `components/library/src/content/page.rs`, we can collapse a nested conditional into `else if let ...`. - In `components/library/src/sorting.rs`, a function takes `&&Page` arguments. Clippy warns about this for efficiency reasons, but we're doing it here to match a particular sorting API, so we'll explicitly ignore the warning.
4 years ago
5 years ago
Fix clippy warnings (#744) Clippy is returning some warnings. Let's fix or explicitly ignore them. In particular: - In `components/imageproc/src/lib.rs`, we implement `Hash` explicitly but derive `PartialEq`. We need to maintain the property that two keys being equal implies the hashes of those two keys are equal. Our `Hash` implementations preserve this, so we'll explicitly ignore the warnings. - In `components/site/src/lib.rs`, we were calling `.into()` on some values that are already of the correct type. - In `components/site/src/lib.rs`, we were using `.map(|x| *x)` in iterator chains to remove a level of indirection; we can instead say `.copied()` (introduced in Rust v1.36) or `.cloned()`. Using `.copied` here is better from a type-checking point of view, but we'll use `.cloned` for now as Rust v1.36 was only recently released. - In `components/templates/src/filters.rs` and `components/utils/src/site.rs`, we were taking `HashMap`s as function arguments but not generically accepting alternate `Hasher` implementations. - In `src/cmd/check.rs`, we use `env::current_dir()` as a default value, but our use of `unwrap_or` meant that we would always retrieve the current directory even when not needed. - In `components/errors/src/lib.rs`, we can use `if let` rather than `match`. - In `components/library/src/content/page.rs`, we can collapse a nested conditional into `else if let ...`. - In `components/library/src/sorting.rs`, a function takes `&&Page` arguments. Clippy warns about this for efficiency reasons, but we're doing it here to match a particular sorting API, so we'll explicitly ignore the warning.
4 years ago
Fix clippy warnings (#744) Clippy is returning some warnings. Let's fix or explicitly ignore them. In particular: - In `components/imageproc/src/lib.rs`, we implement `Hash` explicitly but derive `PartialEq`. We need to maintain the property that two keys being equal implies the hashes of those two keys are equal. Our `Hash` implementations preserve this, so we'll explicitly ignore the warnings. - In `components/site/src/lib.rs`, we were calling `.into()` on some values that are already of the correct type. - In `components/site/src/lib.rs`, we were using `.map(|x| *x)` in iterator chains to remove a level of indirection; we can instead say `.copied()` (introduced in Rust v1.36) or `.cloned()`. Using `.copied` here is better from a type-checking point of view, but we'll use `.cloned` for now as Rust v1.36 was only recently released. - In `components/templates/src/filters.rs` and `components/utils/src/site.rs`, we were taking `HashMap`s as function arguments but not generically accepting alternate `Hasher` implementations. - In `src/cmd/check.rs`, we use `env::current_dir()` as a default value, but our use of `unwrap_or` meant that we would always retrieve the current directory even when not needed. - In `components/errors/src/lib.rs`, we can use `if let` rather than `match`. - In `components/library/src/content/page.rs`, we can collapse a nested conditional into `else if let ...`. - In `components/library/src/sorting.rs`, a function takes `&&Page` arguments. Clippy warns about this for efficiency reasons, but we're doing it here to match a particular sorting API, so we'll explicitly ignore the warning.
4 years ago
5 years ago
Fix clippy warnings (#744) Clippy is returning some warnings. Let's fix or explicitly ignore them. In particular: - In `components/imageproc/src/lib.rs`, we implement `Hash` explicitly but derive `PartialEq`. We need to maintain the property that two keys being equal implies the hashes of those two keys are equal. Our `Hash` implementations preserve this, so we'll explicitly ignore the warnings. - In `components/site/src/lib.rs`, we were calling `.into()` on some values that are already of the correct type. - In `components/site/src/lib.rs`, we were using `.map(|x| *x)` in iterator chains to remove a level of indirection; we can instead say `.copied()` (introduced in Rust v1.36) or `.cloned()`. Using `.copied` here is better from a type-checking point of view, but we'll use `.cloned` for now as Rust v1.36 was only recently released. - In `components/templates/src/filters.rs` and `components/utils/src/site.rs`, we were taking `HashMap`s as function arguments but not generically accepting alternate `Hasher` implementations. - In `src/cmd/check.rs`, we use `env::current_dir()` as a default value, but our use of `unwrap_or` meant that we would always retrieve the current directory even when not needed. - In `components/errors/src/lib.rs`, we can use `if let` rather than `match`. - In `components/library/src/content/page.rs`, we can collapse a nested conditional into `else if let ...`. - In `components/library/src/sorting.rs`, a function takes `&&Page` arguments. Clippy warns about this for efficiency reasons, but we're doing it here to match a particular sorting API, so we'll explicitly ignore the warning.
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. use std::collections::HashMap;
  2. use std::hash::BuildHasher;
  3. use base64::{decode, encode};
  4. use pulldown_cmark as cmark;
  5. use tera::{to_value, try_get_value, Result as TeraResult, Value};
  6. pub fn markdown<S: BuildHasher>(
  7. value: &Value,
  8. args: &HashMap<String, Value, S>,
  9. ) -> TeraResult<Value> {
  10. let s = try_get_value!("markdown", "value", String, value);
  11. let inline = match args.get("inline") {
  12. Some(val) => try_get_value!("markdown", "inline", bool, val),
  13. None => false,
  14. };
  15. let mut opts = cmark::Options::empty();
  16. opts.insert(cmark::Options::ENABLE_TABLES);
  17. opts.insert(cmark::Options::ENABLE_FOOTNOTES);
  18. let mut html = String::new();
  19. let parser = cmark::Parser::new_ext(&s, opts);
  20. cmark::html::push_html(&mut html, parser);
  21. if inline {
  22. html = html
  23. .trim_start_matches("<p>")
  24. // pulldown_cmark finishes a paragraph with `</p>\n`
  25. .trim_end_matches("</p>\n")
  26. .to_string();
  27. }
  28. Ok(to_value(&html).unwrap())
  29. }
  30. pub fn base64_encode<S: BuildHasher>(
  31. value: &Value,
  32. _: &HashMap<String, Value, S>,
  33. ) -> TeraResult<Value> {
  34. let s = try_get_value!("base64_encode", "value", String, value);
  35. Ok(to_value(&encode(s.as_bytes())).unwrap())
  36. }
  37. pub fn base64_decode<S: BuildHasher>(
  38. value: &Value,
  39. _: &HashMap<String, Value, S>,
  40. ) -> TeraResult<Value> {
  41. let s = try_get_value!("base64_decode", "value", String, value);
  42. Ok(to_value(&String::from_utf8(decode(s.as_bytes()).unwrap()).unwrap()).unwrap())
  43. }
  44. #[cfg(test)]
  45. mod tests {
  46. use std::collections::HashMap;
  47. use tera::to_value;
  48. use super::{base64_decode, base64_encode, markdown};
  49. #[test]
  50. fn markdown_filter() {
  51. let result = markdown(&to_value(&"# Hey").unwrap(), &HashMap::new());
  52. assert!(result.is_ok());
  53. assert_eq!(result.unwrap(), to_value(&"<h1>Hey</h1>\n").unwrap());
  54. }
  55. #[test]
  56. fn markdown_filter_inline() {
  57. let mut args = HashMap::new();
  58. args.insert("inline".to_string(), to_value(true).unwrap());
  59. let result = markdown(
  60. &to_value(&"Using `map`, `filter`, and `fold` instead of `for`").unwrap(),
  61. &args,
  62. );
  63. assert!(result.is_ok());
  64. assert_eq!(result.unwrap(), to_value(&"Using <code>map</code>, <code>filter</code>, and <code>fold</code> instead of <code>for</code>").unwrap());
  65. }
  66. // https://github.com/Keats/gutenberg/issues/417
  67. #[test]
  68. fn markdown_filter_inline_tables() {
  69. let mut args = HashMap::new();
  70. args.insert("inline".to_string(), to_value(true).unwrap());
  71. let result = markdown(
  72. &to_value(
  73. &r#"
  74. |id|author_id| timestamp_created|title |content |
  75. |-:|--------:|-----------------------:|:---------------------|:-----------------|
  76. | 1| 1|2018-09-05 08:03:43.141Z|How to train your ORM |Badly written blog|
  77. | 2| 1|2018-08-22 13:11:50.050Z|How to bake a nice pie|Badly written blog|
  78. "#,
  79. )
  80. .unwrap(),
  81. &args,
  82. );
  83. assert!(result.is_ok());
  84. assert!(result.unwrap().as_str().unwrap().contains("<table>"));
  85. }
  86. #[test]
  87. fn base64_encode_filter() {
  88. // from https://tools.ietf.org/html/rfc4648#section-10
  89. let tests = vec![
  90. ("", ""),
  91. ("f", "Zg=="),
  92. ("fo", "Zm8="),
  93. ("foo", "Zm9v"),
  94. ("foob", "Zm9vYg=="),
  95. ("fooba", "Zm9vYmE="),
  96. ("foobar", "Zm9vYmFy"),
  97. ];
  98. for (input, expected) in tests {
  99. let args = HashMap::new();
  100. let result = base64_encode(&to_value(input).unwrap(), &args);
  101. assert!(result.is_ok());
  102. assert_eq!(result.unwrap(), to_value(expected).unwrap());
  103. }
  104. }
  105. #[test]
  106. fn base64_decode_filter() {
  107. let tests = vec![
  108. ("", ""),
  109. ("Zg==", "f"),
  110. ("Zm8=", "fo"),
  111. ("Zm9v", "foo"),
  112. ("Zm9vYg==", "foob"),
  113. ("Zm9vYmE=", "fooba"),
  114. ("Zm9vYmFy", "foobar"),
  115. ];
  116. for (input, expected) in tests {
  117. let args = HashMap::new();
  118. let result = base64_decode(&to_value(input).unwrap(), &args);
  119. assert!(result.is_ok());
  120. assert_eq!(result.unwrap(), to_value(expected).unwrap());
  121. }
  122. }
  123. }