Files
dev/src/ariadne/artifact.rs

95 lines
2.8 KiB
Rust

use std::error::Error;
use std::fs::{self, File};
use std::io::{BufRead, BufReader, BufWriter, Write};
use std::path::Path;
use serde::{Deserialize, Serialize};
use crate::{Delta, Edge, Graph, Node};
pub fn write_graph_artifact(
directory: impl AsRef<Path>,
graph: &Graph,
delta: &[Delta],
) -> std::io::Result<()> {
let directory = directory.as_ref();
fs::create_dir_all(directory)?;
write_json_file(directory.join("metadata.json"), &graph.metadata)?;
write_jsonl_file(directory.join("nodes.jsonl"), graph.nodes.values())?;
write_jsonl_file(directory.join("edges.jsonl"), graph.edges.iter())?;
write_jsonl_file(directory.join("delta.jsonl"), delta.iter())?;
Ok(())
}
pub fn read_graph_artifact(directory: impl AsRef<Path>) -> std::io::Result<Graph> {
let directory = directory.as_ref();
let metadata = read_json_file(directory.join("metadata.json"))?;
let nodes: Vec<Node> = read_jsonl_file(directory.join("nodes.jsonl"))?;
let edges: Vec<Edge> = read_jsonl_file(directory.join("edges.jsonl"))?;
let mut graph = Graph::new(metadata);
for node in nodes {
graph.add_node(node).map_err(invalid_data)?;
}
for edge in edges {
graph.add_edge(edge).map_err(invalid_data)?;
}
Ok(graph)
}
pub fn read_graph_delta(directory: impl AsRef<Path>) -> std::io::Result<Vec<Delta>> {
read_jsonl_file(directory.as_ref().join("delta.jsonl"))
}
fn write_json_file(path: impl AsRef<Path>, value: &impl Serialize) -> std::io::Result<()> {
let file = File::create(path)?;
let writer = BufWriter::new(file);
serde_json::to_writer_pretty(writer, value).map_err(invalid_data)
}
fn read_json_file<T: for<'de> Deserialize<'de>>(path: impl AsRef<Path>) -> std::io::Result<T> {
let file = File::open(path)?;
let reader = BufReader::new(file);
serde_json::from_reader(reader).map_err(invalid_data)
}
fn write_jsonl_file<'a, T: 'a + Serialize>(
path: impl AsRef<Path>,
values: impl IntoIterator<Item = &'a T>,
) -> std::io::Result<()> {
let file = File::create(path)?;
let mut writer = BufWriter::new(file);
for value in values {
serde_json::to_writer(&mut writer, value).map_err(invalid_data)?;
writer.write_all(b"\n")?;
}
Ok(())
}
fn read_jsonl_file<T: for<'de> Deserialize<'de>>(
path: impl AsRef<Path>,
) -> std::io::Result<Vec<T>> {
let file = File::open(path)?;
let reader = BufReader::new(file);
let mut values = Vec::new();
for line in reader.lines() {
let line = line?;
if line.trim().is_empty() {
continue;
}
values.push(serde_json::from_str(&line).map_err(invalid_data)?);
}
Ok(values)
}
fn invalid_data(error: impl Error + Send + Sync + 'static) -> std::io::Error {
std::io::Error::new(std::io::ErrorKind::InvalidData, error)
}