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