-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Is your feature request related to a problem? Please describe.
currently, the query_as! macro performs Into::into on returned items to convert them into the types of the struct fields. This solution only works, obviously, when the conversion is infallible. what if the conversion is fallible? sqlx requires one to implement Decode to fallibly convert from database types. The problem is that these have to be checked at run-time, as their type checking is done by the author in the impl Type, etc. However, what if your type can be converted (fallibly) from a built-in, already type-checked sqlx type (Uuid, String, etc.)?
Describe the solution you'd like
query_as! should use .try_into() in its generated code instead of into(). If it fails, it should take the TryInto::Error and box it (much like Decode::decode) and bubble it up as an sqlx::Error.
From what I can tell, this would not break any previous code, due to the pre-existing blanket impl of impl<T, U> TryFrom<U> for T where U: From<T>, and the Err would just be Infallible.
Here is an example of when this would be useful:
struct Username(String);
impl TryFrom<String> for Username {
type Error = &'static str;
fn try_from(s: String) -> Result<Self, Self::Error> {
for c in c.chars() {
if !('a'..='z').contains(c) {
return "invalid character: (must be a-z)";
}
}
return Self(s)
}
}
struct User {
username: Username,
bio: String,
}
sqlx::query_as!(User, "SELECT username, bio FROM users"); // valid query, as `Username` implements `TryFrom` a built-in sqlx type.Of course, this may seem like unneeded validation for a database retrieval, but one may want to avoid implementing From due to it exposing a hole in data validation, meaning they have to go through the hassle of implementing Decode then still not have compile-time type safety for their query.
Describe alternatives you've considered
Manually implementing Decode.