use alloc::{collections::VecDeque, vec::Vec};
use super::{AdviceInputs, AdviceMap};
use crate::{Felt, Word, crypto::merkle::MerkleStore};
#[derive(Clone, Debug, Default)]
pub struct AdviceStackBuilder {
stack: VecDeque<Felt>,
}
impl AdviceStackBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn push_element(&mut self, value: Felt) -> &mut Self {
self.stack.push_back(value);
self
}
pub fn push_elements<I>(&mut self, values: I) -> &mut Self
where
I: IntoIterator<Item = Felt>,
{
self.stack.extend(values);
self
}
pub fn push_for_adv_push(&mut self, slice: &[Felt]) -> &mut Self {
for elem in slice.iter().rev() {
self.stack.push_back(*elem);
}
self
}
pub fn push_for_adv_loadw(&mut self, word: Word) -> &mut Self {
for elem in word.iter() {
self.stack.push_back(*elem);
}
self
}
pub fn push_for_adv_pipe(&mut self, slice: &[Felt]) -> &mut Self {
assert!(
slice.len().is_multiple_of(8),
"push_for_adv_pipe requires slice length to be a multiple of 8, got {}",
slice.len()
);
for elem in slice.iter() {
self.stack.push_back(*elem);
}
self
}
pub fn push_u64_slice(&mut self, values: &[u64]) -> &mut Self {
self.stack.extend(values.iter().map(|&v| Felt::new(v)));
self
}
pub fn build(self) -> AdviceInputs {
AdviceInputs {
stack: self.stack.into(),
map: AdviceMap::default(),
store: MerkleStore::default(),
}
}
pub fn build_with(self, map: AdviceMap, store: MerkleStore) -> AdviceInputs {
AdviceInputs { stack: self.stack.into(), map, store }
}
pub fn build_vec_u64(self) -> Vec<u64> {
self.stack.into_iter().map(|f| f.as_canonical_u64()).collect()
}
pub fn into_elements(self) -> Vec<Felt> {
self.stack.into_iter().collect()
}
}