cryptocurrency_parser 0.1.1

A parser of different cryptocurrencies
Documentation
use pest::Parser;
use pest_derive::Parser;
use serde_json::json;
use std::collections::HashMap;
use std::fs::File;
use std::io::BufRead;
use std::io::{self, Write};
use std::path::Path;
use thiserror::Error;

#[derive(Parser)]
#[grammar = "./grammar.pest"]
pub struct BlockchainParser;

#[derive(Error, Debug)]
pub enum ParseError {
    #[error("Parsing error: {0}")]
    ParsingError(String),
    #[error("File error: {0}")]
    FileError(#[from] io::Error),
    #[error("JSON serialization error: {0}")]
    JsonError(#[from] serde_json::Error),
}

pub fn parse_entry(input: &str) -> Result<HashMap<String, String>, ParseError> {
    let mut entry_map: HashMap<String, String> = HashMap::new();
    let pairs = BlockchainParser::parse(Rule::entry, input)
        .map_err(|e| ParseError::ParsingError(format!("{:?}", e)))?;

    for pair in pairs {
        if pair.as_rule() == Rule::entry {
            for inner_pair in pair.into_inner() {
                match inner_pair.as_rule() {
                    Rule::name => {
                        let name = inner_pair.into_inner().next().unwrap().as_str();
                        entry_map.insert("Name".to_string(), name.to_string());
                    }
                    Rule::date_entry => {
                        let date = inner_pair.into_inner().next().unwrap().as_str();
                        entry_map.insert("Date".to_string(), date.to_string());
                    }
                    Rule::open => {
                        let open = inner_pair.into_inner().next().unwrap().as_str();
                        entry_map.insert("Open".to_string(), open.to_string());
                    }
                    Rule::close => {
                        let close = inner_pair.into_inner().next().unwrap().as_str();
                        entry_map.insert("Close".to_string(), close.to_string());
                    }
                    Rule::high => {
                        let high = inner_pair.into_inner().next().unwrap().as_str();
                        entry_map.insert("High".to_string(), high.to_string());
                    }
                    Rule::low => {
                        let low = inner_pair.into_inner().next().unwrap().as_str();
                        entry_map.insert("Low".to_string(), low.to_string());
                    }
                    Rule::volume => {
                        let volume = inner_pair.into_inner().next().unwrap().as_str();
                        entry_map.insert("Volume".to_string(), volume.to_string());
                    }
                    _ => {}
                }
            }
        }
    }

    Ok(entry_map)
}

pub fn parse_file_to_json(input_path: &Path, output_path: &Path) -> Result<(), ParseError> {
    let file = File::open(input_path)?;
    let reader = io::BufReader::new(file);

    let mut entries = Vec::new();

    for line in reader.lines() {
        let line = line?;
        match parse_entry(&line) {
            Ok(entry) => entries.push(entry),
            Err(e) => eprintln!("Error parsing line: {}", e),
        }
    }

    let json_data = json!(entries);
    let pretty_json = serde_json::to_string_pretty(&json_data)?;

    let mut output_file = File::create(output_path)?;
    write!(output_file, "{}", pretty_json)?;

    Ok(())
}