#![warn(missing_docs)]
#![doc = include_str!("../README.md")]
mod config;
mod constraint;
mod context;
mod element;
mod encoder;
mod indexed_witness;
mod polynomial;
mod preamble;
mod source;
mod witness;
pub(crate) mod bytes;
use std::fs::{File, OpenOptions};
use std::io;
use std::ops::{Deref, DerefMut};
use std::path::Path;
pub use config::{AtomicConfig, BaseConfig, Config};
pub use constraint::Constraint;
pub use context::{Context, ContextUnit};
pub use element::{Element, FixedText, Scalar};
pub use encoder::Encoder;
pub use indexed_witness::IndexedWitness;
pub use polynomial::Polynomial;
pub use preamble::Preamble;
pub use source::Source;
pub use witness::Witness;
pub type CircuitDescriptionUnit = CircuitDescription<()>;
pub type CircuitDescriptionFile = CircuitDescription<File>;
#[derive(Debug)]
pub struct CircuitDescription<S> {
source: S,
preamble: Preamble,
}
impl CircuitDescription<File> {
pub fn open_read<P>(path: P) -> io::Result<Self>
where
P: AsRef<Path>,
{
OpenOptions::new()
.read(true)
.open(path)
.and_then(Self::from_reader)
}
}
impl<S> CircuitDescription<S>
where
S: io::Read,
{
pub fn by_ref(&mut self) -> CircuitDescription<&mut S> {
CircuitDescription {
source: self.source.by_ref(),
preamble: self.preamble,
}
}
pub fn context(&mut self) -> Context<&mut S> {
let ctx = self.by_ref();
Context::with_cdf(ctx)
}
}
impl<S> CircuitDescription<S>
where
S: io::Read + io::Seek,
{
pub fn from_reader(source: S) -> io::Result<Self> {
let mut cdf = Self {
source,
preamble: Preamble::default(),
};
let ctx = &mut cdf.context();
cdf.preamble = Preamble::try_from_context(&AtomicConfig, ctx)?;
Ok(cdf)
}
pub fn fetch_constraint(&mut self, idx: usize) -> io::Result<Constraint> {
self.preamble
.constraint_offset(idx)
.ok_or_else(|| {
io::Error::new(io::ErrorKind::Other, "attempt to fetch invalid constraint")
})
.map(|ofs| io::SeekFrom::Start(ofs as u64))
.and_then(|ofs| self.source.seek(ofs))?;
let config = self.preamble.config;
let mut ctx = self.context();
Constraint::try_from_context(&config, &mut ctx)
}
pub fn fetch_witness(&mut self, idx: usize) -> io::Result<Witness> {
self.preamble
.witness_offset(idx)
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "attempt to fetch invalid witness"))
.map(|ofs| io::SeekFrom::Start(ofs as u64))
.and_then(|ofs| self.source.seek(ofs))?;
let config = self.preamble.config;
let mut ctx = self.context();
Witness::try_from_context(&config, &mut ctx)
}
pub fn fetch_source(&mut self, idx: usize) -> io::Result<FixedText<{ Source::PATH_LEN }>> {
let ofs = self.preamble.source_cache_offset(idx);
let ofs = io::SeekFrom::Start(ofs as u64);
self.source.seek(ofs)?;
let config = self.preamble.config;
let mut ctx = self.context();
FixedText::try_from_context(&config, &mut ctx)
}
}
impl<S> CircuitDescription<S> {
pub fn into_inner(self) -> S {
self.source
}
pub const fn config(&self) -> &Config {
&self.preamble.config
}
pub const fn preamble(&self) -> &Preamble {
&self.preamble
}
}
impl<S> Deref for CircuitDescription<S> {
type Target = S;
fn deref(&self) -> &Self::Target {
&self.source
}
}
impl<S> DerefMut for CircuitDescription<S> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.source
}
}