1use anyhow::Result;
4use binius_core::oracle::OracleId;
5use binius_field::{as_packed_field::PackScalar, ExtensionField, TowerField};
6
7use crate::builder::{
8 types::{F, U},
9 ConstraintSystemBuilder,
10};
11
12pub fn pack<FInput, FOutput>(
13 oracle_id: OracleId,
14 builder: &mut ConstraintSystemBuilder,
15 name: impl ToString,
16) -> Result<OracleId>
17where
18 F: ExtensionField<FInput> + ExtensionField<FOutput>,
19 FInput: TowerField,
20 FOutput: TowerField + ExtensionField<FInput>,
21 U: PackScalar<FInput> + PackScalar<FOutput>,
22{
23 if FInput::TOWER_LEVEL == FOutput::TOWER_LEVEL {
24 return Ok(oracle_id);
25 }
26
27 let packed_id =
28 builder.add_packed(name, oracle_id, FOutput::TOWER_LEVEL - FInput::TOWER_LEVEL)?;
29
30 if let Some(witness) = builder.witness() {
31 let values_witness = witness.get::<FInput>(oracle_id)?;
32
33 witness.set(packed_id, values_witness.repacked::<FOutput>())?;
34 }
35
36 Ok(packed_id)
37}