2

This

extern crate postgres;

use postgres::{Connection, SslMode};

struct User {
    reference: String,
    email: String,
    firstname: String,
    lastname: String
}

static DB_URI: &'static str = "postgres://postgres:postgres@localhost/test";

fn main() {

    let conn = Connection::connect(DB_URI, &SslMode::None).unwrap();
    let trans = conn.transaction().unwrap();

    //...

}

fn insert_user<'a>(trans: &'a postgres::Transaction, user: &User) -> &'a postgres::Result {
    //...
}

is throwing an error

error: wrong number of type arguments: expected 1, found 0 [E0243]
fn insert_user<'a>(trans: &'a postgres::Transaction, user: &User) -> &'a postgres::Result {
                                                                         ^~~~~~~~~~~~~~~~

What is missing here? I just want to return a result of an executed query.

UPDATE So I modified the function line like this:

fn insert_user(trans: &postgres::Transaction, user: &User) -> &postgres::Result<()> {

to trick the compiler into revealing the correct return type and it gave me this:

mismatched types:
 expected `core::result::Result<(), postgres::error::Error>`,
    found `core::result::Result<postgres::Rows<'_>, postgres::error::Error>`

however when I tried to match the return type like this:

fn insert_user(trans: &postgres::Transaction, user: &User) -> &postgres::Result<postgres::Rows<'_>, postgres::error::Error> {

it's now throwing a new error:

error: use of undeclared lifetime name `'_` [E0261]
fn insert_user(trans: &postgres::Transaction, user: &User) -> postgres::Result<postgres::Rows<'_>, postgres::error::Error> {
                                                                                              ^~
ha9u63a7
  • 6,233
  • 16
  • 73
  • 108
Caballero
  • 11,546
  • 22
  • 103
  • 163
  • 2
    It's exactly what it says. You've given it the wrong number of type arguments. [`Result`](http://sfackler.github.io/rust-postgres/doc/v0.9.1/postgres/type.Result.html) takes the type for the returned valid value. – Veedrac Jun 11 '15 at 13:37

2 Answers2

4

Looking at the documentation for the crate postgres, we can see that the type postgres::Result is generic over one type argument:

type Result<T> = Result<T, Error>;

Normally you would have two options:

  1. Specify the type yourself if you know what it is: postgres::Result<MyType>
  2. Let the compiler infer it for you (if it has enough information elsewhere): postgres::Result<_>

However in a return type (what comes after the ->) type inference is not triggered, so only option 1. is available.

(Hint: you still have one trick up your sleeve to find out the desired type. You can try specifying the unit type: ... -> postgres::Result<()> and check if the compiler complains with an error such as "expected MyType, found ()". This means you want to specify ... -> postgres::Result<MyType>.)

mdup
  • 7,889
  • 3
  • 32
  • 34
  • Thanks for the trick advice, made some progress with it, but the compiler is still complaining, I'm sure there's a reason. – Caballero Jun 11 '15 at 14:05
  • 1
    I would advise to reinstate the lifetime `'a` you had, and use it instead of `'_`, since the compiler is not inferring it. – Matthieu M. Jun 11 '15 at 15:04
  • @Caballero indeed you went just one step too far in copying the error message, because `'_` is an anonymous lifetime and it's discouraged that you name a lifetime `'_`. Usually they're called `'a` or `'b`. Seeing [your second question in a row](http://stackoverflow.com/questions/30784279/rust-borrowed-value-does-not-live-long-enough), I suggest that maybe you want to pause writing code for a little while and get to know the language with the [Rust book](https://doc.rust-lang.org/book) (specifically here, the [lifetimes section](https://doc.rust-lang.org/book/lifetimes.html)). – mdup Jun 11 '15 at 15:14
  • @mdup that section doesn't help with my particular situation, all the examples are very simple. – Caballero Jun 11 '15 at 16:11
2

Result is defined as postgres::Result<T> (we say it is generic over T). Depending on the innards of the insert_user function, it could be Result<bool>, Result<u64>, Result<()> or something else entierly.

For example, the execute method on Transaction returns a Result<u64>, so that is a likely variant.

llogiq
  • 13,815
  • 8
  • 40
  • 72