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
[0.16] improve api around binding collections to statements. #104
Comments
I am wondering if instead we should remove all the Minimal example: trait Bindable {
#[doc(hidden)]
fn bind(self, index: usize, statement: &mut Statement) -> Result<()>;
}
impl Statement {
fn bind(&mut self, index: usize, bindable: impl Bindable) -> Result<&mut self> {
bindable.bind(index, &mut self)?;
Ok(self)
}
}
/// Implement all of these internally
impl Bindable for i8 {
fn bind(self, index: usize, statement: &mut Statement) -> Result<()> { ... }
} And now the client side API is: let mut statement = session.statement("SELECT * FROM foo WHERE id = ?");
statement.bind(0, 5i8)?;
let result = statement.execute().await?; Thoughts? Here's a rust playground that shows the concept in action: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=a2c4e6387d4fa8ebfe4a91769913c26e |
I'm silly, because we do infact have this via I wonder if we should just unify around that then... it's silly to have both APIs imo. We should offer a single concise way of doing things for the 1.0 api surface. |
Sure, happy to unify around the type-driven approach. I don't think that currently works for collections though, so the original intention of this issue still stands. |
Okay, so I think that we can unify everything underneath a
Example code: let mut list = List::new();
list.append(1f32)?;
list.append(5f32)?;
let mut map = Map::new();
map.append_pair("key", "value")?;
let mut statement = prepared_statement.bind();
statement.bind(0, list)?;
statement.bind("key_for_map", map)?;
statement.bind("another_value", 5000f32)?;
statement.bind("null_value", CassNull)?;
let result = statement.execute().await?; I also want to implement let vec = vec![1u32, 2, 3, 4];
let list: List = vec.into_iter().collect()?;
let hash_map = hashmap!{"foo" => 1u32};
let map: Map = hash_map.into_iter().collect()?; |
I like this. Can you sketch out all the methods that would be needed on the two traits, just so we can see how it will work out? I'm always a little worried about coherence and intelligible error messages when an API starts to get clever with traits. You're right of course wrt The design above is missing some type safety though - recall Cassandra collections are homogeneous, but as stated this allows
(Tuples are different - they are allowed to be heterogeneous and so they don't need the extra type parameter.) I totally agree wrt |
#91 was a "hackfix", but I realized that we indeed do have a
CassCollection
trait, and we can most definitely use it here, insofar as we can reviveset_collection(&mut self, index: usize, collection: impl CassCollection)
This issue tracks that betterment.
The text was updated successfully, but these errors were encountered: