-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question: type-safe builder for updates #12
Comments
I would love to see this too. For the first iteration, I didn't have a clear model of how to do it safely, especially with the myriad things that a single update expression can do at a time. If I were to make something, it would probably need to be a procedural macro that could parse out the various elements and then turn that into a structure that you could use. |
I was looking into https://docs.rs/derive_builder/0.12.0/derive_builder/ a bit, seems like it could be relevant. It automatically generates a builder pattern for a struct. We'd want it to do this for a copy of the struct that has optional values for everything I think. Then we could use that struct to create the update expression and pass the names and values. Definitely not a complete picture yet, but wanted to share anyway :) |
Also found this one: https://github.com/yanganto/struct-patch/tree/main let mut patch = Story::new_empty_patch();
patch.archived = Some(true);
println!("patch: {:#?}", patch);
|
Continuing that patch test a bit: let mut patch = Story::new_empty_patch();
patch.archived = Some(true);
println!("patch: {:#?}", patch);
let json = serde_json::to_value(&patch).unwrap();
let non_none_keys: Vec<_> = json
.as_object()
.unwrap()
.iter()
.filter(|(_, v)| !v.is_null())
.map(|(k, _)| k.to_string())
.collect();
let update_expression = format!(
"SET {}",
non_none_keys
.iter()
.map(|key| { format!("#{} = :{}", key, key) })
.collect::<Vec<String>>()
.join(", ")
);
println!("update_expression: {:#?}", update_expression);
let mut expression = expr::Update::new(&update_expression);
for key in non_none_keys {
expression = expression.name(&format!("#{}", key), &key);
expression = expression.value(&format!(":{}", key), &json[key]);
}
println!("expression: {:#?}", expression);
Kind of cool! Definitely not ideal serialising it to json to figure out the non-None keys, and taking the value from the json, but maybe this will help us get into the right direction :) |
Throwing this out there as possibly relevant |
I was wondering if you've thought about making the updates type-safe somehow.
Right now the updates are done like this:
But what if they could be done like:
I'm not sure how this would work yet (still relatively new to rust), but from an api perspective this would be amazing. You'd abstract away the dynamodb syntax and prevent bugs due to typos there as well. For more specific expressions you could still use the current approach.
Curious about your opinion!
The text was updated successfully, but these errors were encountered: