Skip to content

Commit 2530482

Browse files
committed
Switch from handlebars to liquid for rendering output templates
This allows for the use of filters (https://github.com/Shopify/liquid/wiki/Liquid-for-Designers#standard-filters) for relatively easy string replacements
1 parent 69fcc94 commit 2530482

File tree

3 files changed

+33
-13
lines changed

3 files changed

+33
-13
lines changed

Cargo.toml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,13 @@ aws-config = "0.56.0"
1313
aws-sdk-s3 = "0.29.0"
1414
aws_lambda_events = { version = "0.10.0", default-features = false, features = ["s3"] }
1515
chrono = "0.4.26"
16-
handlebars = "4.3.7"
16+
liquid = "0.26"
1717

1818
lambda_runtime = "0.8.1"
19-
log = "0.4.20"
20-
pretty_env_logger = "0.5.0"
2119
routefinder = "0.5.3"
2220
serde_json = "1.0.105"
2321
tokio = { version = "1", features = ["macros"] }
2422
tracing = { version = "0.1", features = ["log"] }
25-
tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt"] }
23+
tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "env-filter", "tracing-log"] }
2624
urlencoding = "2.1.3"
2725

README.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ The following environment variables must be set for the function to run properly
6464

6565
| `OUTPUT_TEMPLATE`
6666
| _required byt empty by default_
67-
| A link:https://docs.rs/handlebars/4.3.7/handlebars/index.html[handlebars] template which produces a compatible path for outputting the file into the S3 bucket
67+
| A link:https://crates.io/crates/liquid[liquid] template which produces a compatible path for outputting the file into the S3 bucket.
6868

6969
|===
7070

src/main.rs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
use aws_lambda_events::event::s3::{S3Entity, S3Event};
22
use aws_sdk_s3::Client as S3Client;
3-
use handlebars::Handlebars;
43
use lambda_runtime::{run, service_fn, Error, LambdaEvent};
5-
use log::*;
64
use routefinder::Router;
7-
//use tracing::*;
5+
use tracing::log::*;
86

97
use std::collections::HashMap;
108

@@ -15,17 +13,19 @@ async fn function_handler(event: LambdaEvent<S3Event>, client: &S3Client) -> Res
1513
.expect("You must define OUTPUT_TEMPLATE in the environment");
1614

1715
let mut router = Router::new();
18-
let mut hb = Handlebars::new();
19-
hb.register_template_string("output", &output_template)?;
16+
let template = liquid::ParserBuilder::with_stdlib()
17+
.build()?
18+
.parse(&output_template)?;
2019

2120
router.add(input_pattern, 1)?;
2221
info!("Processing records: {event:?}");
2322

2423
for entity in entities_from(event.payload)? {
2524
debug!("Processing {entity:?}");
25+
2626
if let Some(source_key) = entity.object.key {
2727
let parameters = add_builtin_parameters(captured_parameters(&router, &source_key)?);
28-
let output_key = hb.render("output", &parameters)?;
28+
let output_key = template.render(&parameters)?;
2929
info!("Copying {source_key:?} to {output_key:?}");
3030
if let Some(bucket) = entity.bucket.name {
3131
debug!("Sending a copy request for {bucket} with {source_key} to {output_key}");
@@ -46,9 +46,8 @@ async fn function_handler(event: LambdaEvent<S3Event>, client: &S3Client) -> Res
4646

4747
#[tokio::main]
4848
async fn main() -> Result<(), Error> {
49-
pretty_env_logger::init();
5049
tracing_subscriber::fmt()
51-
.with_max_level(tracing::Level::INFO)
50+
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
5251
// disable printing the name of the module in every log line.
5352
.with_target(false)
5453
// disabling time is handy because CloudWatch will add the ingestion time.
@@ -199,4 +198,27 @@ mod tests {
199198
let event: S3Event = serde_json::from_str(&raw_buf)?;
200199
Ok(event)
201200
}
201+
202+
/**
203+
* Quickly validate that the liquid rendering of things works properly
204+
*/
205+
#[test]
206+
fn test_rendering() {
207+
let template = liquid::ParserBuilder::with_stdlib()
208+
.build()
209+
.unwrap()
210+
.parse("databases/{{database}}/{{table | remove:'public.'}}/ds={{ds}}/{{filename}}")
211+
.unwrap();
212+
let mut parameters: HashMap<String, String> = HashMap::new();
213+
parameters = add_builtin_parameters(parameters);
214+
parameters.insert("database".into(), "oltp".into());
215+
parameters.insert("table".into(), "public.a_table".into());
216+
parameters.insert("filename".into(), "some.parquet".into());
217+
parameters.insert("ds".into(), "2023-09-05".into());
218+
let output_key = template.render(&parameters).unwrap();
219+
assert_eq!(
220+
output_key,
221+
"databases/oltp/a_table/ds=2023-09-05/some.parquet"
222+
);
223+
}
202224
}

0 commit comments

Comments
 (0)