w3resource

Rust Function: Read and Parse CSV with Error handling


Write a Rust function that reads a CSV file, parses it into structured data, and handles parsing errors.

Sample Solution:

Rust Code:

use std::fs; // Import the fs module for file handling
use std::error::Error; // Import the Error trait for error handling
use std::path::Path; // Import the Path struct for handling file paths
use csv::ReaderBuilder; // Import the ReaderBuilder struct from the csv crate for reading CSV files

// Define a struct to represent the data structure of each row in the CSV file
#[derive(Debug)]
struct Record {
    name: String,
    age: u32,
    city: String,
}

// Function to read and parse the CSV file
fn read_csv(file_path: &str) -> Result<Vec<Record>, Box<dyn Error>> {
    let file = fs::File::open(file_path)?; // Open the file
    let mut reader = ReaderBuilder::new().has_headers(false).from_reader(file); // Create a CSV reader without assuming headers
    let mut records = Vec::new(); // Initialize a vector to store parsed records

    // Iterate over each record in the CSV file
    for result in reader.records() {
        let record = result?; // Unwrap the record or propagate any parsing errors

        // Parse the fields of the record into the Record struct
        let name = record.get(0).ok_or("Missing name field")?.to_string(); // Extract the name field
        let age_str = record.get(1).ok_or("Missing age field")?; // Extract the age field as a string
        let age: u32 = age_str.parse()?; // Parse the age string into a u32
        let city = record.get(2).ok_or("Missing city field")?.to_string(); // Extract the city field

        // Create a Record instance and push it to the records vector
        records.push(Record { name, age, city });
    }

    Ok(records) // Return the parsed records vector
}

fn main() {
    let file_path = "data.csv"; // Specify the path of the CSV file
    let csv_data = "John,25,New York\nAlice,30,Los Angeles\nBob,35,Chicago"; // CSV data to write to the file

    // Create the CSV file with the specified data
    fs::write(file_path, csv_data).expect("Failed to create CSV file");

    match read_csv(file_path) {
        Ok(records) => {
            println!("Parsed records:");
            for record in records {
                println!("{:?}", record);
            }
        }
        Err(err) => eprintln!("Error reading CSV file: {}", err),
    }
}

Output:

Parsed records:
Record { name: "John", age: 25, city: "New York" }
Record { name: "Alice", age: 30, city: "Los Angeles" }
Record { name: "Bob", age: 35, city: "Chicago" }

Explanation:

Here's a brief explanation of the above Rust code:

  • Imports: The code imports the necessary modules and structs from the standard library (std::fs, std::error::Error, std::path::Path) and from the "csv" crate (csv::ReaderBuilder).
  • Record Struct: It defines a struct "Record" with fields 'name', 'age', and 'city' to represent the structure of each row in the CSV file. The #[derive(Debug)] attribute is used to automatically derive the "Debug" trait for pretty printing.
  • read_csv Function: This function takes a file path as input and returns a "Result" containing a vector of "Record" instances or an error. It opens the file, creates a CSV reader without assuming headers, and iterates over each record in the file. For each record, it parses the fields into a "Record" struct and adds it to a vector. If any parsing error occurs, it returns the error.
  • main Function: In the "main()" function, it specifies the file path for the CSV file and creates sample CSV data. It then creates the CSV file with the sample data using fs::write. Next, it calls the "read_csv()" function to parse the CSV file. If parsing is successful, it prints the parsed records. If an error occurs, it prints an error message.

Go to:


PREV : Rust Function: Read file with Error handling.
NEXT : Rust Program: Count Lines in File with Error Handling.

Rust Code Editor:

What is the difficulty level of this exercise?

Test your Programming skills with w3resource's quiz.



Follow us on Facebook and Twitter for latest update.