use crate::error::Result;
use crate::executor::execute_graph;
use crate::format::GlobalHeader;
use crate::graph::TaskGraph;
use crate::inspector::{DebugReport, ParcodeInspector};
use crate::io::SeqWriter;
use crate::reader::{ParcodeFile, ParcodeNative};
use crate::visitor::ParcodeVisitor;
use std::io::Write;
use std::path::Path;
use std::sync::Arc;
#[derive(Debug)]
pub struct Parcode;
impl Parcode {
pub fn builder() -> ParcodeOptions {
ParcodeOptions::default()
}
#[cfg(not(target_arch = "wasm32"))]
pub fn save<T, P>(path: P, root_object: &T) -> Result<()>
where
T: ParcodeVisitor + Sync,
P: AsRef<Path>,
{
ParcodeOptions::default().save(path, root_object)
}
pub fn write<T, W>(writer: W, root_object: &T) -> Result<()>
where
T: ParcodeVisitor + Sync,
W: Write + Send,
{
ParcodeOptions::default().write(writer, root_object)
}
pub fn serialize<T>(root_object: &T) -> Result<Vec<u8>>
where
T: ParcodeVisitor + Sync,
{
let mut buffer = Vec::with_capacity(4096);
Self::write(&mut buffer, root_object)?;
Ok(buffer)
}
#[cfg(not(target_arch = "wasm32"))]
pub fn load<T, P>(path: P) -> Result<T>
where
T: ParcodeNative,
P: AsRef<Path>,
{
ParcodeFile::open(path)?.load()
}
pub fn load_bytes<T>(data: impl Into<Arc<Vec<u8>>>) -> Result<T>
where
T: ParcodeNative,
{
ParcodeFile::from_bytes(data)?.load()
}
#[cfg(not(target_arch = "wasm32"))]
pub fn open<P>(path: P) -> Result<ParcodeFile>
where
P: AsRef<Path>,
{
ParcodeFile::open(path)
}
pub fn open_bytes(data: impl Into<Arc<Vec<u8>>>) -> Result<ParcodeFile> {
ParcodeFile::from_bytes(data)
}
pub fn write_sync<T, W>(writer: W, root_object: &T) -> Result<()>
where
T: ParcodeVisitor,
W: Write + Send,
{
ParcodeOptions::default().write_sync(writer, root_object)
}
#[cfg(not(target_arch = "wasm32"))]
pub fn save_sync<T, P>(path: P, root_object: &T) -> Result<()>
where
T: ParcodeVisitor,
P: AsRef<Path>,
{
ParcodeOptions::default().save_sync(path, root_object)
}
#[cfg(not(target_arch = "wasm32"))]
pub fn inspect<P: AsRef<Path>>(path: P) -> Result<DebugReport> {
ParcodeInspector::inspect(path)
}
pub fn inspect_bytes(data: impl Into<Arc<Vec<u8>>>) -> Result<DebugReport> {
let file = ParcodeFile::from_bytes(data)?;
ParcodeInspector::inspect_file(&file)
}
}
#[derive(Debug, Default)]
pub struct ParcodeOptions {
use_compression: bool,
}
impl ParcodeOptions {
pub fn compression(mut self, enable: bool) -> Self {
self.use_compression = enable;
self
}
#[cfg(not(target_arch = "wasm32"))]
pub fn save<T, P>(&self, path: P, root_object: &T) -> Result<()>
where
T: ParcodeVisitor + Sync,
P: AsRef<Path>,
{
let file = std::fs::File::create(path)?;
self.write(file, root_object)
}
pub fn write<'a, T, W>(&self, writer: W, root_object: &'a T) -> Result<()>
where
T: ParcodeVisitor + Sync,
W: Write + Send,
{
let mut graph = TaskGraph::<'a>::new();
root_object.visit(&mut graph, None, None);
let seq_writer = SeqWriter::new(writer);
let registry = crate::compression::CompressorRegistry::new();
let root_child_ref = execute_graph(&graph, &seq_writer, ®istry, self.use_compression)?;
let header = GlobalHeader::new(root_child_ref.offset, root_child_ref.length);
seq_writer.write_all(&header.to_bytes())?;
seq_writer.flush()?;
Ok(())
}
#[cfg(not(target_arch = "wasm32"))]
pub fn save_sync<T, P>(&self, path: P, root_object: &T) -> Result<()>
where
T: ParcodeVisitor,
P: AsRef<Path>,
{
let file = std::fs::File::create(path)?;
self.write_sync(file, root_object)
}
pub fn write_sync<'a, T, W>(&self, writer: W, root_object: &'a T) -> Result<()>
where
T: ParcodeVisitor,
W: Write + Send,
{
let mut graph = TaskGraph::<'a>::new();
root_object.visit(&mut graph, None, None);
let seq_writer = SeqWriter::new(writer);
let registry = crate::compression::CompressorRegistry::new();
#[cfg(feature = "parallel")]
let root_child_ref = crate::executor::execute_graph_serial(
&graph,
&seq_writer,
®istry,
self.use_compression,
)?;
#[cfg(not(feature = "parallel"))]
let root_child_ref = execute_graph(&graph, &seq_writer, ®istry, self.use_compression)?;
let header = GlobalHeader::new(root_child_ref.offset, root_child_ref.length);
seq_writer.write_all(&header.to_bytes())?;
seq_writer.flush()?;
Ok(())
}
}