1use std::{io, mem};
2
3use crate::{
4 Config, Constraint, DecodableElement, DecoderContext, Element, EncodableElement,
5 EncoderContext, Witness,
6};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub struct Preamble {
11 pub witnesses: usize,
13 pub constraints: usize,
15 pub config: Config,
17}
18
19impl Preamble {
20 pub const LEN: usize = 2 * mem::size_of::<usize>() + Config::LEN;
22
23 pub const fn new(witnesses: usize, constraints: usize, config: Config) -> Self {
25 Self {
26 witnesses,
27 constraints,
28 config,
29 }
30 }
31
32 pub fn witness_offset(&self, idx: usize) -> Option<usize> {
34 (idx < self.witnesses).then(|| Self::LEN + idx * Witness::len(&self.config))
35 }
36
37 pub fn constraint_offset(&self, idx: usize) -> Option<usize> {
39 (idx < self.constraints).then(|| {
40 Self::LEN
41 + self.witnesses * Witness::len(&self.config)
42 + idx * Constraint::len(&self.config)
43 })
44 }
45
46 pub fn source_cache_offset(&self) -> usize {
48 Self::LEN
49 + self.witnesses * Witness::len(&self.config)
50 + self.constraints * Constraint::len(&self.config)
51 }
52}
53
54impl Default for Preamble {
55 fn default() -> Self {
56 Self {
57 witnesses: 1,
58 constraints: 0,
59 config: Default::default(),
60 }
61 }
62}
63
64impl Element for Preamble {
65 fn len(ctx: &Config) -> usize {
66 2 * usize::len(ctx) + Config::len(ctx)
67 }
68
69 fn validate(&self, preamble: &Preamble) -> io::Result<()> {
70 self.witnesses.validate(preamble)?;
71 self.constraints.validate(preamble)?;
72 self.config.validate(preamble)?;
73
74 Ok(())
75 }
76}
77
78impl EncodableElement for Preamble {
79 fn to_buffer(&self, ctx: &mut EncoderContext, buf: &mut [u8]) {
80 let buf = self.witnesses.encode(ctx, buf);
81 let buf = self.constraints.encode(ctx, buf);
82 let _ = self.config.encode(ctx, buf);
83 }
84}
85
86impl DecodableElement for Preamble {
87 fn try_from_buffer_in_place<'a, 'b>(
88 &'a mut self,
89 ctx: &DecoderContext<'a>,
90 buf: &'b [u8],
91 ) -> io::Result<()> {
92 Self::validate_buffer(ctx.config(), buf)?;
93
94 let buf = self.witnesses.try_decode_in_place(ctx, buf)?;
95 let buf = self.constraints.try_decode_in_place(ctx, buf)?;
96 let _ = self.config.try_decode_in_place(ctx, buf)?;
97
98 Ok(())
99 }
100}