Hello there,
I am quite new to Rust. I come from a C++ and Python background but I am very impressed with Rust and want to write code with it.
I am currently working through the Handbook, however, I have some questions.
Currently I am trying to write a program that loads data from a .csv file and loads it into a Postgres database.
I have the following structure:
Cargo.toml
Cargo.lock
src
- csv_operataions.rs
- data_structure.rs
- db_operations.rs
- main.rs
My main.rs
looks like this:
use std::process;
use postgres::{Client, NoTls, Error};
pub mod csv_operations;
pub mod db_operations;
mod data_structure;
use data_structure::Record;
fn main() {
println!("Try to connect to database.");
let mut client: Client;
db_operations::db_access(&mut client);
println!("Try to read .csv file.");
let mut vec: Vec<Record> = Vec::new();
if let Err(err) = csv_operations::read_csv(&mut vec) {
println!("Error while trying to read csv file: {}", err);
process::exit(1);
}
// Here I would have a function, something like
db_operations::write_to_databse(&mut vec, &mut client);
}
My db_operations.rs
looks like this:
use postgres::{Client, NoTls, Error};
use chrono::NaiveDate;
pub fn db_access(client: &mut Client) -> Result<(), Error> {
client = &mut Client::connect("postgres://userpassword@localhost/database", NoTls)?;
Ok(())
}
pub fn write_to_databse(vec: &mut Vec<Record>, client: &mut Client) -> Result<(), Error> {
// Write data from vector into database
Ok()
}
My csv_operations
is something like this:
use std::error::Error;
use csv::ReaderBuilder;
use serde::Deserialize;
use super::data_structure::Record;
use postgres::Client;
pub fn read_csv(vec: &mut Vec<Record>) -> Result<(), Box<dyn Error>> {
let path = "/path/with/file.csv";
let mut reader = ReaderBuilder::new()
.delimiter(b';')
.from_path(path)?;
for record in reader.deserialize() {
let record: Record = record?;
//vec.push(record);
}
Ok(())
}
The file data_structure.rs
just defines the struct so I can make a vector from the csv file and write it into the database.
use serde::Deserialize;
#[derive(Deserialize)]
pub struct Record {
#[serde(alias = "ID")]
id: i32,
...
That does not work because main.rs
declares client
without initialising. In C++ I would have a header file that handles all of the database stuff and a header that handles all of the csv stuff and I would include that in my main file and then create the objects as needed and pass them to the right functions to get the work done, just to separate it logically.
How would I go about something like that in Rust? (the code is still incomplete because I'm currently working on it and I'm still questioning this approach)
Also both csv_operations.rs
and db_operations.csv
use the same data structure and so I include that with super::data_structure
but is this really the way to go? I just want a simple struct to use across source files so I don't want to make an extra library.
Cheers,