1use std::ops::Deref;
6
7use ff::Field;
8
9use crate::{
10 error::Error,
11 expressions::ExprBuilder,
12 info_traits::CreateQuery,
13 query::{Advice, Fixed, Instance},
14};
15
16pub trait ColumnType: std::fmt::Debug + Copy + Clone + PartialEq + Eq + std::hash::Hash {
18 fn query_cell<F: Field, E: ExprBuilder<F>>(&self, index: usize, at: Rotation) -> E;
20}
21
22#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
24pub enum Any {
25 Fixed,
27 Advice,
29 Instance,
31}
32
33impl ColumnType for Any {
34 fn query_cell<F: Field, E: ExprBuilder<F>>(&self, index: usize, at: Rotation) -> E {
35 match self {
36 Any::Fixed => Fixed.query_cell(index, at),
37 Any::Advice => Advice.query_cell(index, at),
38 Any::Instance => Instance.query_cell(index, at),
39 }
40 }
41}
42
43impl ColumnType for Fixed {
44 fn query_cell<F: Field, E: ExprBuilder<F>>(&self, index: usize, at: Rotation) -> E {
45 E::FixedQuery::query_expr(index, at)
46 }
47}
48
49impl ColumnType for Advice {
50 fn query_cell<F: Field, E: ExprBuilder<F>>(&self, index: usize, at: Rotation) -> E {
51 E::AdviceQuery::query_expr(index, at)
52 }
53}
54
55impl ColumnType for Instance {
56 fn query_cell<F: Field, E: ExprBuilder<F>>(&self, index: usize, at: Rotation) -> E {
57 E::InstanceQuery::query_expr(index, at)
58 }
59}
60
61#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
63pub struct Column<C: ColumnType> {
64 index: usize,
65 column_type: C,
66}
67
68impl<C: ColumnType> Column<C> {
69 pub fn new(index: usize, column_type: C) -> Self {
71 Self { index, column_type }
72 }
73
74 pub fn index(&self) -> usize {
76 self.index
77 }
78
79 pub fn column_type(&self) -> &C {
81 &self.column_type
82 }
83
84 pub fn query_cell<F: Field, E: ExprBuilder<F>>(&self, at: Rotation) -> E {
86 self.column_type.query_cell(self.index, at)
87 }
88}
89
90impl From<Column<Fixed>> for Column<Any> {
91 fn from(value: Column<Fixed>) -> Self {
92 Self {
93 index: value.index,
94 column_type: Any::Fixed,
95 }
96 }
97}
98
99impl TryFrom<Column<Any>> for Column<Fixed> {
100 type Error = Error;
101
102 fn try_from(value: Column<Any>) -> Result<Self, Self::Error> {
103 match value.column_type {
104 Any::Fixed => Ok(Self {
105 index: value.index,
106 column_type: Fixed,
107 }),
108 c => Err(Error::ExpectedFixed(c)),
109 }
110 }
111}
112
113impl From<Column<Advice>> for Column<Any> {
114 fn from(value: Column<Advice>) -> Self {
115 Self {
116 index: value.index,
117 column_type: Any::Advice,
118 }
119 }
120}
121
122impl TryFrom<Column<Any>> for Column<Advice> {
123 type Error = Error;
124
125 fn try_from(value: Column<Any>) -> Result<Self, Self::Error> {
126 match value.column_type {
127 Any::Advice => Ok(Self {
128 index: value.index,
129 column_type: Advice,
130 }),
131 c => Err(Error::ExpectedAdvice(c)),
132 }
133 }
134}
135
136impl From<Column<Instance>> for Column<Any> {
137 fn from(value: Column<Instance>) -> Self {
138 Self {
139 index: value.index,
140 column_type: Any::Instance,
141 }
142 }
143}
144
145impl TryFrom<Column<Any>> for Column<Instance> {
146 type Error = Error;
147
148 fn try_from(value: Column<Any>) -> Result<Self, Self::Error> {
149 match value.column_type {
150 Any::Instance => Ok(Self {
151 index: value.index,
152 column_type: Instance,
153 }),
154 c => Err(Error::ExpectedInstance(c)),
155 }
156 }
157}
158
159#[derive(Debug, PartialEq, Eq, Copy, Clone)]
161pub struct Cell {
162 pub region_index: RegionIndex,
164 pub row_offset: usize,
166 pub column: Column<Any>,
168}
169
170pub type Rotation = i32;
172
173pub trait RotationExt {
175 fn cur() -> Self;
177
178 fn next() -> Self;
180
181 fn prev() -> Self;
183}
184
185impl RotationExt for Rotation {
186 fn cur() -> Self {
187 0
188 }
189
190 fn next() -> Self {
191 1
192 }
193
194 fn prev() -> Self {
195 -1
196 }
197}
198
199#[derive(Eq, Hash, PartialEq, Debug, Copy, Clone)]
201pub struct RegionIndex(usize);
202
203impl Deref for RegionIndex {
204 type Target = usize;
205
206 fn deref(&self) -> &Self::Target {
207 &self.0
208 }
209}
210
211impl From<usize> for RegionIndex {
212 fn from(value: usize) -> Self {
213 Self(value)
214 }
215}