I have a MySQL database to store information about my cats. One table holds all the known races, another table holds all the known colors. Than a final table to save the name and age of my cat and a foreign key to the races- and colors-table matching the right race/color of the cat.
Now I have written a function to return all the cats in the database in a vector. To do that I first need to retrieve the two foreign keys needed to get the right color/race.
I thought I got close until Rust spitted out a ton of errors. This is my code:
fn read(&mut self) -> &std::vec::Vec<Cat> {
let selected_cat_rows : std::vec::Vec<std::result::Result<mysql::Row, mysql::Error>> =
self.conn.prep_exec("SELECT name, age, color_id, race_id FROM cats", ()).unwrap().collect();
let mut cats : std::vec::Vec<Cat> = std::vec::Vec::<Cat>::new();
for row in &selected_cat_rows {
//Retrieve color name from color-table by color_id
let color_id : u64 = row.unwrap().take("color_id").unwrap();
let mut color : std::vec::Vec<String> = std::vec::Vec::<String>::new();
let color_rows : std::vec::Vec<std::result::Result<mysql::Row, mysql::Error>> = self.conn.prep_exec("SELECT color_name FROM colors WHERE id = :color_id", params!("color_id" => color_id)).unwrap().collect();
for subrow in &color_rows {
color.push(subrow.unwrap().take("color_name").unwrap());
}
//Retrieve race name from race-table by race_id
let race_id : u64 = row.unwrap().take("race_id").unwrap();
let mut race : std::vec::Vec<String> = std::vec::Vec::<String>::new();
let race_rows : std::vec::Vec<std::result::Result<mysql::Row, mysql::Error>> = self.conn.prep_exec("SELECT race_name FROM races WHERE id = :race_id", params!("race_id" => race_id)).unwrap().collect();
for subrow in &race_rows {
color.push(subrow.unwrap().take("race_name").unwrap());
}
let cat : Cat = Cat {
name: row.unwrap().take("name").unwrap(),
age: row.unwrap().take("age").unwrap(),
color: color[0].parse().unwrap(),
race: race[0].parse().unwrap(),
};
cats.push(cat);
}
&cats
}
All the errors:
error[E0507]: cannot move out of `*row` which is behind a shared reference
--> src/main.rs:437:38
|
437 | let color_id : u64 = row.unwrap().take("color_id").unwrap();
| ^^^
| |
| move occurs because `*row` has type `std::result::Result<mysql::Row, mysql::Error>`, which does not implement the `Copy` trait
| help: consider borrowing the `Result`'s content: `row.as_ref()`
error[E0507]: cannot move out of `*subrow` which is behind a shared reference
--> src/main.rs:441:32
|
441 | color.push(subrow.unwrap().take("color_name").unwrap());
| ^^^^^^
| |
| move occurs because `*subrow` has type `std::result::Result<mysql::Row, mysql::Error>`, which does not implement the `Copy` trait
| help: consider borrowing the `Result`'s content: `subrow.as_ref()`
error[E0507]: cannot move out of `*row` which is behind a shared reference
--> src/main.rs:445:37
|
445 | let race_id : u64 = row.unwrap().take("race_id").unwrap();
| ^^^
| |
| move occurs because `*row` has type `std::result::Result<mysql::Row, mysql::Error>`, which does not implement the `Copy` trait
| help: consider borrowing the `Result`'s content: `row.as_ref()`
error[E0507]: cannot move out of `*subrow` which is behind a shared reference
--> src/main.rs:449:32
|
449 | color.push(subrow.unwrap().take("race_name").unwrap());
| ^^^^^^
| |
| move occurs because `*subrow` has type `std::result::Result<mysql::Row, mysql::Error>`, which does not implement the `Copy` trait
| help: consider borrowing the `Result`'s content: `subrow.as_ref()`
error[E0507]: cannot move out of `*row` which is behind a shared reference
--> src/main.rs:453:27
|
453 | name: row.unwrap().take("name").unwrap(),
| ^^^
| |
| move occurs because `*row` has type `std::result::Result<mysql::Row, mysql::Error>`, which does not implement the `Copy` trait
| help: consider borrowing the `Result`'s content: `row.as_ref()`
error[E0507]: cannot move out of `*row` which is behind a shared reference
--> src/main.rs:454:26
|
454 | age: row.unwrap().take("age").unwrap(),
| ^^^
| |
| move occurs because `*row` has type `std::result::Result<mysql::Row, mysql::Error>`, which does not implement the `Copy` trait
| help: consider borrowing the `Result`'s content: `row.as_ref()`
error[E0515]: cannot return reference to local variable `cats`
--> src/main.rs:462:13
|
462 | &cats
| ^^^^^ returns a reference to data owned by the current function
error: aborting due to 7 previous errors
Some errors have detailed explanations: E0507, E0515.
For more information about an error, try `rustc --explain E0507`.
error: could not compile `cat_generator`.
It are the typical Rust-errors like 'move happened', 'borrow result', 'No copy trait implemented'...
But I don't get it...
For example this piece of code let color_id : u64 = row.unwrap().take("color_id").unwrap();
returns those kind of errors. row is just the variable from the foreach-loop... Why does using that variable give an error?
What causes these errors and how to fix it?