95 lines
2.8 KiB
Rust
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)
|
|
}
|