Skip to content
Snippets Groups Projects
Commit f24af45b authored by Benjamin Wingfield's avatar Benjamin Wingfield
Browse files

simplify reading: don't deserialise, just validate

parent ee28abae
No related branches found
No related tags found
No related merge requests found
use std::fs;
use std::{fs, io};
use std::path::Path;
use log::{info, warn};
use rusqlite::Connection;
use crate::request::job::JobRequest;
use anyhow::Result;
use crate::request::message::MessageError;
// once a message is read, start
pub fn add_job(conn: &Connection, job: Result<JobRequest, MessageError>, path: &Path) -> Result<()> {
pub fn add_job(conn: &Connection, job: Result<(), io::Error>, path: &Path) -> Result<()> {
info!("Adding job to db");
// read raw message content again to store in db
let json: String = fs::read_to_string(path)?;
......
use std::io;
use std::path::{Path, PathBuf};
use anyhow::Result;
use clap::Parser;
use log::info;
use rusqlite::Connection;
use serde::de::Error;
use request::job::JobRequest;
use crate::db::job::add_job;
use crate::request::message::{Message, MessageError};
use crate::request::message::Message;
mod db;
mod request;
......@@ -42,10 +43,10 @@ fn main() {
let schema = request::schema::load_schema(args.schema_dir.as_path());
let messages: Result<Vec<Message>> = request::message::from_dir(args.message_dir.as_path());
let messages: Result<Vec<Message>, io::Error> = request::message::from_dir(args.message_dir.as_path());
for message in messages.unwrap() {
let job: Result<JobRequest, MessageError> = message.read(&schema);
let job: Result<(), io::Error> = message.read(&schema);
let _ = add_job(&conn, job, message.path.as_path());
}
......
pub mod read;
pub mod message;
pub mod schema;
pub mod job;
\ No newline at end of file
use std::fs;
use std::{fs, io};
use std::io::ErrorKind;
use std::path::{Path, PathBuf};
use jsonschema::JSONSchema;
use log::{info, warn};
use serde_json::Value;
use crate::request::read;
use anyhow::Result;
use crate::request::job::JobRequest;
use crate::request::message::MessageError::JSONValidationError;
#[derive(Debug)]
pub enum MessageError {
JSONValidationError,
JSONDecodeError,
DeserialisationError,
MessageReadError,
}
pub struct Message {
pub path: PathBuf
pub path: PathBuf,
}
pub fn from_dir(dir: &Path) -> Result<Vec<Message>> {
pub fn from_dir(dir: &Path) -> Result<Vec<Message>, io::Error> {
let mut list: Vec<Message> = Vec::new();
let paths= read::get_message_paths(dir)?;
let paths = get_message_paths(dir)?;
for path in paths {
let m = Message { path };
......@@ -35,13 +24,13 @@ pub fn from_dir(dir: &Path) -> Result<Vec<Message>> {
}
impl Message {
pub fn read(&self, schema: &JSONSchema) -> Result<JobRequest, MessageError> {
pub fn read(&self, schema: &JSONSchema) -> Result<(), io::Error> {
let json: Value = self.parse_untyped_json()?;
match self.validate(&json, schema) {
Ok(_) => {
info!("Message is valid");
self.parse_json(json)
Ok(())
}
Err(err) => {
warn!("Message fails validation");
......@@ -51,7 +40,7 @@ impl Message {
}
}
fn validate(&self, json_string: &Value, schema: &JSONSchema) -> Result<(), MessageError> {
fn validate(&self, json_string: &Value, schema: &JSONSchema) -> Result<(), io::Error> {
info!("Validating raw message against JSON validate");
match schema.validate(json_string) {
Ok(_) => Ok(()),
......@@ -60,33 +49,29 @@ impl Message {
warn!("Validation error: {}", error);
warn!("Instance path: {}", error.instance_path);
}
Err(JSONValidationError)
let err = io::Error::new(ErrorKind::Other, "JSON validation error");
Err(err)
}
}
}
fn read_file(&self) -> Result<String, MessageError> {
fn read_file(&self) -> Result<String, io::Error> {
let path: &Path = self.path.as_path();
info!("Reading message at {}", path.display());
fs::read_to_string(path).map_err(|err| {
warn!("Can't read message job request at path {}: {}", path.display(), err);
MessageError::MessageReadError
})
let contents = fs::read_to_string(path)?;
Ok(contents)
}
fn parse_json(&self, value: Value) -> Result<JobRequest, MessageError> {
info!("Deserialising valid JSON into typed Rust object");
// from_value is a generic function, so request JobRequest specifically
serde_json::from_value::<JobRequest>(value)
.map_err(|_| MessageError::DeserialisationError)
}
fn parse_untyped_json(&self) -> Result<Value, MessageError> {
info!("Parsing JSON into untyped structure");
fn parse_untyped_json(&self) -> Result<Value, io::Error> {
let json_string = self.read_file()?;
info!("{}", json_string);
// from_value is a generic function, so request Value (generic json) specifically
serde_json::from_str::<Value>(&json_string)
.map_err(|_| MessageError::JSONDecodeError)
info!("Parsing JSON into untyped structure: {}", json_string);
let value: Value = serde_json::from_str(&json_string)?;
Ok(value)
}
}
fn get_message_paths(dir: &Path) -> Result<Vec<PathBuf>, io::Error> {
fs::read_dir(dir)?
.map(|res| res.map(|e| e.path()))
.collect::<Result<Vec<PathBuf>, io::Error>>()
}
use std::{fs, io};
use std::io::Error;
use std::path::{Path, PathBuf};
pub fn get_message_paths(dir: &Path) -> Result<Vec<PathBuf>, Error> {
fs::read_dir(dir)?
.map(|res| res.map(|e| e.path()))
.collect::<Result<Vec<PathBuf>, io::Error>>()
}
\ No newline at end of file
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment