7 releases (breaking)
Uses new Rust 2024
| 0.6.0 | Jul 23, 2025 |
|---|---|
| 0.5.0 | Jul 21, 2025 |
| 0.4.0 | Jun 29, 2025 |
| 0.3.0 | Jun 18, 2025 |
| 0.1.0 | Jun 13, 2025 |
#158 in Template engine
430 downloads per month
27KB
478 lines
stri
stri is a set of procedural macros for string interpolation.
Usage Example
use stri::{si, sql};
fn main(){
let name = "Ahmed";
let age = 63;
let height = 180.5;
// `si!`: str interpolation used to interpolate variables normally
assert_eq!(
si!("my name is {name}, i am {age} years old and my height is {height}"),
"my name is Ahmed, i am 63 years old and my height is 180.5",
);
//
//
//
let note = r#"My friend's name is Ali"#;
// but for `sql` where `String` must be wrapped with single quote and each quote
// inside it must be escaped then `sql!` is used.
assert_eq!(
sql!("INSERT INTO users (name, age, height, note) VALUES ({name}, {age}, {height}, {note})"),
r#"INSERT INTO users (name, age, height, note) VALUES ('Ahmed', 63, 180.5, 'My friend''s name is Ali')"#,
);
//
//
//
let note = r#"[' " > < &]"#; // these are html special characters: ' " > < &
// if you want to sanitize html special characters then add `~html` as a suffix to
// the variable name (works with `&str` and `String` only)
assert_eq!(
sql!("INSERT INTO users (name, age, height, note) VALUES ({name}, {age}, {height}, {~html note})"),
r#"INSERT INTO users (name, age, height, note) VALUES ('Ahmed', 63, 180.5, '[' " > < &]')"#,
);
//
//
//
//
//
// If the `chrono` feature is enabled
// Note: chrono::{
// DateTime, Duration, FixedOffset, NaiveDate,
// NaiveDateTime, NaiveTime, TimeZone, Weekday
// };
// are the only supported types
use chrono::NaiveDateTime;
let dt = NaiveDateTime::parse_from_str("2015-09-05 23:56:04", "%Y-%m-%d %H:%M:%S").unwrap();
assert_eq!(
si!("date and time is: {dt}"),
"date and time is: 2015-09-05 23:56:04"
);
assert_eq!(
sql!("SELECT {dt}::TIMESTAMP AS date_time"),
"SELECT '2015-09-05 23:56:04'::TIMESTAMP AS date_time"
);
//
//
//
//
//
// if the `rust_decimal` feature is enabled
use rust_decimal::Decimal;
let d = Decimal::new(1225, 2); // 12.25;
assert_eq!(si!("Decimal is: {d}"), "Decimal is: 12.25");
assert_eq!(
sql!("SELECT {d}::DECIMAL AS d"),
"SELECT 12.25::DECIMAL AS d"
);
}
file! macro
For longer string or sql content, you can externalize it into a separate file and use the file! macro to include it. The file! macro intelligently applies the logic of the si! or sql! macros internally, determined by the extension of the specified file.
Example
File: src/example.txt
my name is {name}, i am {age} years old and my height is {height}
File: src/example.sql
INSERT INTO users (name, age, height, note) VALUES ({name}, {age}, {height}, {note})
use stri::file;
fn main(){
let name = "Ahmed";
let age = 63;
let height = 180.5;
let note = r#"My friend's name is Ali"#;
//
//
//
assert_eq!(
file!("src/example.txt"),
"my name is Ahmed, i am 63 years old and my height is 180.5",
);
//
//
//
assert_eq!(
file!("src/example.sql"),
r#"INSERT INTO users (name, age, height, note) VALUES ('Ahmed', 63, 180.5, 'My friend''s name is Ali')"#,
);
}
dir! macro
The dir! macro allows you to concatenate the content of multiple files within a specified directory. It reads all files only at the first level of the given directory, joins their content with a newline character (\n), and intelligently processes them based on the file extensions within the directory:
-
If all files have the .sql extension:
sql!macro's logic will be applied. -
Otherwise:
si!macro's logic will be applied.
Note: The order in which files are read and concatenated is dependent on the the behavior of std::fs::ReadDir.
Example
Dir: src
src/ ├── sql │ ├── 1_insert.sql │ └── 2_delete.sql ├── txt │ ├── 1_name.txt │ └── 2_age.txt └── main.rs
File: src/sql/1_insert.sql
INSERT INTO users (name, age, height, note) VALUES ({name}, {age}, {height}, {note});
File: src/sql/2_insert.sql
DELETE FROM users WHERE name={name};
File: src/txt/1_name.txt
My name is {name}
File: src/txt/2_age.txt
I am {age} years old
File src/main.rs
use stri::dir;
fn main(){
let name = "Ahmed";
let age = 63;
//
//
//
assert_eq!(
dir!("src/sql"),
"INSERT INTO users (name, age, height, note) VALUES ('Ahmed', 63, 180.5, 'My friend''s name is Ali');\nDELETE FROM users WHERE name='Ahmed';"
);
//
//
//
assert_eq!(dir!("src/txt"), "My name is Ahmed\nI am 63 years old")
}
Contribution
If you encounter any issues or want to suggest a feature, please open an issue in github.
License Information
"stri" is licensed under Ethical Use License (EUL v1.0). see LICENSE for full license details.
Dependencies
~0.2–1MB
~21K SLoC