Skip to content
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

feat: ToSql trait #33

Open
DrewMcArthur opened this issue Jul 22, 2023 · 4 comments
Open

feat: ToSql trait #33

DrewMcArthur opened this issue Jul 22, 2023 · 4 comments

Comments

@DrewMcArthur
Copy link

implementations by other libraries for reference:

having a trait would be helpful in order to clarify which types can be passed to args!, and would make the crate more extensible

pub trait ToSql {
    fn to_sql(&self) -> Result<Value, Error>;
}

ideally would also implement this trait for commonly used types

@DrewMcArthur
Copy link
Author

seems like i can just use Into<libsql_client::Value> in place of a trait - if that's accurate, feel free to close this, but hopefully it's helpful for someone down the road!

@psarna
Copy link
Contributor

psarna commented Jul 24, 2023

Yeah, the idea behind args! is that it can accept anything that implement Into<Value>. I suppose we could also add a try_args! for things that implement TryInto<Value>, which would make the interface accept Result as well -- then it will be functionally matching ToSql from all these other crates

@DrewMcArthur
Copy link
Author

gotcha. i initially opened this issue when i was looking at implementing a connector for this library in axum-login, but Into<Value> (or TryInto) solves that for me.

now, i'm having trouble going the other way - from a Value to a Uuid, specifically. are there any examples with variables more complex than a str or usize? the docs seem pretty sparse imo.

for reference, here's my current attempt:

    fn from_db_row(row: libsql_client::Row) -> Result<Self, Errors> {
        let id: Uuid = row // (Row)
            .try_column::<String>("id") // Result<String, Error>
            .map_err(Errors::DbStoredUuidParsingError) // Result<String, Errors>
            .map(|v: String| Uuid::parse_str(v.as_str())) // Result<Result<Uuid, Error>, Errors>
            .unwrap() // Result<Uuid, Errors>
            .unwrap(); // Uuid
    // ...

but this gives me:

error[E0271]: type mismatch resolving `<String as TryFrom<&Value>>::Error == String`
  --> src/models/users.rs:19:27
   |
19 |             .try_column::<String>("id")
   |                           ^^^^^^ expected `String`, found `Infallible`
   |
note: required by a bound in `Row::try_column`
  --> /Users/drewmca/.cargo/git/checkouts/libsql-client-rs-57d771ddb99c75d4/5675782/src/lib.rs:72:45
   |
72 |     pub fn try_column<V: TryFrom<&'a Value, Error = String>>(
   |                                             ^^^^^^^^^^^^^^ required by this bound in `Row::try_column`

and i get the same thing if i don't specify the type for try_column. any hints?

@DrewMcArthur
Copy link
Author

this seems to have worked for me.

impl User {
    fn from_db_row(row: libsql_client::Row) -> Result<Self, Errors> {
        let id: Uuid;
        let username: String;

        let val = &row.values[0];
        if let Value::Text { value } = val {
            id = Uuid::parse_str(value.as_str()).map_err(Errors::UuidParsingError)?;
        }

        let val = &row.values[1];
        if let Value::Text { value } = val {
            username = value.to_string();
        }

        Ok(Self { id, username })
    }
}

which i found in the turso docs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants