Initial commit

main
kirbylife 2023-08-30 00:34:26 -06:00
commit a72dc06a54
5 changed files with 271 additions and 0 deletions

2
.gitignore vendored 100644
View File

@ -0,0 +1,2 @@
/target
Cargo.lock

17
Cargo.toml 100644
View File

@ -0,0 +1,17 @@
[package]
name = "tera_thousands"
version = "0.1.0"
authors = ["kirbylife <hola@kirbylife.dev>"]
license = "MIT"
readme = "README.md"
homepage = "https://git.kirbylife.dev/kirbylife/tera_thousands"
repository = "https://git.kirbylife.dev/kirbylife/tera_thousands"
documentation = "https://docs.rs/tera_thousands"
description = "Simple filter for tera to split the numbers by thousands"
keywords = ["tera", "template", "formatting", "separators", "numbers"]
categories = ["template-engine"]
edition = "2021"
[dependencies]
thousands = "0.2.0"
tera = { version = "1.19.0", default-features = false }

19
LICENSE.md 100644
View File

@ -0,0 +1,19 @@
Copyright (c) 2023 Kirbylife <hola@kirbylife.dev>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

59
README.md 100644
View File

@ -0,0 +1,59 @@
# tera_thousands
## Simple filter for tera to split the numbers by thousands
### dependencies:
- [tera](https://crates.io/crates/tera)
- [thousands](https://crates.io/crates/thousands)
### Usage
The usage is simple:
First add this crate to the `Cargo.toml` file:
```Toml
tera_thousands = "0.1.0"
```
Now add the filter to your Tera instance:
```Rust
let mut tera = Tera::default();
tera.register_filter("separate_with_commas", tera_thousands::separate_with_commas);
```
You can now divide the numbers in your tera template with commas:
```Rust
let mut context = Context::new();
context.insert("number", &123456);
let output = tera
.render_str("{{ number | separate_with_commas }}", &context)
.expect("Expected a number");
assert_eq!(output, "123,456");
```
Also, you can use it with Rocket or any framework compatible with Tera.
For example, this is how it would be used with Rocket:
```
use rocket_dyn_templates::Template;
use tera_thousands::separate_with_commas;
#[launch]
fn rocket() -> _ {
rocket::build()
.attach(Template::custom(|engines| {
engines.tera.register_filter("separate_with_commas", separate_with_commas)
}))
.mount(...)
}
```
The possible options are:
- `separate_with_commas`
- `separate_with_dots`
- `separate_with_spaces`
- `separate_with_underscores`
### TO-DO
- [ ] An addition customizable filter from the template
Contributors are welcome :).

174
src/lib.rs 100644
View File

@ -0,0 +1,174 @@
use std::{collections::HashMap, hash::BuildHasher};
use tera::{to_value, Error, Value};
use thousands::Separable;
pub fn separate_with_commas<S: BuildHasher>(
value: &Value,
_: &HashMap<String, Value, S>,
) -> tera::Result<Value> {
if value.is_f64() {
Ok(to_value(value.as_f64().unwrap().separate_with_commas()).unwrap())
} else if value.is_i64() {
Ok(to_value(value.as_i64().unwrap().separate_with_commas()).unwrap())
} else if value.is_u64() {
Ok(to_value(value.as_u64().unwrap().separate_with_commas()).unwrap())
} else {
Err(Error::msg("Expected a number"))
}
}
pub fn separate_with_spaces<S: BuildHasher>(
value: &Value,
_: &HashMap<String, Value, S>,
) -> tera::Result<Value> {
if value.is_f64() {
Ok(to_value(value.as_f64().unwrap().separate_with_spaces()).unwrap())
} else if value.is_i64() {
Ok(to_value(value.as_i64().unwrap().separate_with_spaces()).unwrap())
} else if value.is_u64() {
Ok(to_value(value.as_u64().unwrap().separate_with_spaces()).unwrap())
} else {
Err(Error::msg("Expected a number"))
}
}
pub fn separate_with_dots<S: BuildHasher>(
value: &Value,
_: &HashMap<String, Value, S>,
) -> tera::Result<Value> {
if value.is_f64() {
Ok(to_value(value.as_f64().unwrap().separate_with_dots()).unwrap())
} else if value.is_i64() {
Ok(to_value(value.as_i64().unwrap().separate_with_dots()).unwrap())
} else if value.is_u64() {
Ok(to_value(value.as_u64().unwrap().separate_with_dots()).unwrap())
} else {
Err(Error::msg("Expected a number"))
}
}
pub fn separate_with_underscores<S: BuildHasher>(
value: &Value,
_: &HashMap<String, Value, S>,
) -> tera::Result<Value> {
if value.is_f64() {
Ok(to_value(value.as_f64().unwrap().separate_with_underscores()).unwrap())
} else if value.is_i64() {
Ok(to_value(value.as_i64().unwrap().separate_with_underscores()).unwrap())
} else if value.is_u64() {
Ok(to_value(value.as_u64().unwrap().separate_with_underscores()).unwrap())
} else {
Err(Error::msg("Expected a number"))
}
}
#[cfg(test)]
mod tests {
use super::{
separate_with_commas, separate_with_dots, separate_with_spaces, separate_with_underscores,
};
use tera::{Context, Tera};
#[test]
fn separate_with_commas_test() {
let mut context = Context::new();
context.insert("integer_number", &10000);
context.insert("negative_number", &-69420);
context.insert("float_number", &1234.567);
let mut tera = Tera::default();
tera.register_filter("separate_with_commas", separate_with_commas);
let s_int = tera
.render_str("{{ integer_number | separate_with_commas }}", &context)
.expect("Expected a number");
let s_neg = tera
.render_str("{{ negative_number | separate_with_commas }}", &context)
.expect("Expected a number");
let s_flt = tera
.render_str("{{ float_number | separate_with_commas }}", &context)
.expect("Expected a number");
assert_eq!(s_int, "10,000");
assert_eq!(s_neg, "-69,420");
assert_eq!(s_flt, "1,234.567");
}
#[test]
fn separate_with_dots_test() {
let mut context = Context::new();
context.insert("integer_number", &10000);
context.insert("negative_number", &-69420);
context.insert("float_number", &1234.567);
let mut tera = Tera::default();
tera.register_filter("separate_with_dots", separate_with_dots);
let s_int = tera
.render_str("{{ integer_number | separate_with_dots }}", &context)
.expect("Expected a number");
let s_neg = tera
.render_str("{{ negative_number | separate_with_dots }}", &context)
.expect("Expected a number");
let s_flt = tera
.render_str("{{ float_number | separate_with_dots }}", &context)
.expect("Expected a number");
assert_eq!(s_int, "10.000");
assert_eq!(s_neg, "-69.420");
assert_eq!(s_flt, "1.234.567");
}
#[test]
fn separate_with_spaces_test() {
let mut context = Context::new();
context.insert("integer_number", &10000);
context.insert("negative_number", &-69420);
context.insert("float_number", &1234.567);
let mut tera = Tera::default();
tera.register_filter("separate_with_spaces", separate_with_spaces);
let s_int = tera
.render_str("{{ integer_number | separate_with_spaces }}", &context)
.expect("Expected a number");
let s_neg = tera
.render_str("{{ negative_number | separate_with_spaces }}", &context)
.expect("Expected a number");
let s_flt = tera
.render_str("{{ float_number | separate_with_spaces }}", &context)
.expect("Expected a number");
assert_eq!(s_int, "10 000");
assert_eq!(s_neg, "-69 420");
assert_eq!(s_flt, "1 234.567");
}
#[test]
fn separate_with_underscores_test() {
let mut context = Context::new();
context.insert("integer_number", &10000);
context.insert("negative_number", &-69420);
context.insert("float_number", &1234.567);
let mut tera = Tera::default();
tera.register_filter("separate_with_underscores", separate_with_underscores);
let s_int = tera
.render_str("{{ integer_number | separate_with_underscores }}", &context)
.expect("Expected a number");
let s_neg = tera
.render_str(
"{{ negative_number | separate_with_underscores }}",
&context,
)
.expect("Expected a number");
let s_flt = tera
.render_str("{{ float_number | separate_with_underscores }}", &context)
.expect("Expected a number");
assert_eq!(s_int, "10_000");
assert_eq!(s_neg, "-69_420");
assert_eq!(s_flt, "1_234.567");
}
}