Conflicting messages when I try to provide an implementation for mysql::FromRow

Does anyone have a working implementation of mysql::FromRow? It might show me what I'm doing wrong. I've looked for one, but maybe I'm looking in the wrong place.

Cargo is giving me two different errors. The first version says

17  |     fn from_row_opt(row: Row) -> Result<CallInfoRow, FromRowError> {
    |                                  ^^^^^^              ------------ help: remove this generic argument
    |                                  |
    |                                  expected 1 generic argument
    |

but when I try to do as the help suggests, I get even more confusing errors:

17 |     fn from_row_opt(row: Row) -> Result<CallInfoRow> {
   |                                  ^^^^^^^^^^^^^^^^^^^
   |                                  |
   |                                  expected struct `FromRowError`, found enum `Error`
   |                                  help: change the output type to match the trait: `std::result::Result<CallInfoRow, mysql::FromRowError>`
   |
   = note: expected signature `fn(mysql::Row) -> std::result::Result<_, mysql::FromRowError>`
              found signature `fn(mysql::Row) -> std::result::Result<_, mysql::Error>`

error[E0308]: mismatched types
  --> src/main.rs:17:34
   |
17 |     fn from_row_opt(row: Row) -> Result<CallInfoRow> {
   |        ------------              ^^^^^^^^^^^^^^^^^^^ expected enum `Result`, found `()`
   |        |
   |        implicitly returns `()` as its body has no tail or `return` expression
   |
   = note:   expected enum `std::result::Result<CallInfoRow, mysql::Error>`
           found unit type `()`

Full main.rs in case it is helpful:

use mysql::*;
use mysql::prelude::*;

#[derive(Debug, PartialEq, Eq)]
struct CallInfoRow {
    id: i32,
    page: i32,
}

#[derive(Debug, PartialEq, Eq)]
struct CallInfoRowDupe {
    id: i32,
    page: i32,
}

impl FromRow for CallInfoRow {
    fn from_row_opt(row: Row) -> Result<CallInfoRow> {
        Ok(row);
    }
}

fn main() {
    println!("A message");
}

You should remove the semicolon to return the value.

    fn from_row_opt(row: Row) -> Result<CallInfoRow> {
-        Ok(row);
+        Ok(row)
    }

First, remove the semicolon.

     fn from_row_opt(row: Row) -> Result<CallInfoRow> {
-        Ok(row);
+        Ok(row)
     }

But next, I suggest not using glob imports on non-prelude modules.

-use mysql::*;

Then I believe you'll no longer be importing their Result type alias and will be able to go back to something like

fn from_row_opt(row: Row) -> Result<CallInfoRow, mysql::FromRowError> 
1 Like

Thanks for the suggestions, but ultimately adding

use core::result::Result;

fixed the confusing messages. I'm don't understand why Rust needs std::result::Result and core::result::Result, but (after removing the extra semi-colon) that was the problem.

They're the same type. The problem is that mysql exports a Result type alias that you were importing with use mysql::*;

I was trying to trim my example down to a minimum that would show the problem. My original needs use mysql::*. So adding core::result::Result fixed the problem, but why?

The reason it worked is that explicitly named imports override * imports, so now you're importing everything but mysql::Result from mysql.

But note that you never need an * import; you can always replace it with the names you actually intend to use:

use mysql::{x, y, z};
1 Like

Here are some more examples.

Even if you work around the problem today, the glob import might bite you again tomorrow when you update your dependencies and they've added more items in their namespace. Presumably they take more care with their prelude, precisely because of issues like this.

Thanks all for your help. These glob imports are more trouble than I thought they'd be.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.