Initial commit
commit
a72dc06a54
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
Cargo.lock
|
|
@ -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 }
|
|
@ -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.
|
|
@ -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 :).
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue