1use std::ops::Deref;
6
7use ff::Field;
8use thiserror::Error;
9
10use crate::{
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(Copy, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
24pub enum Any {
25 Fixed,
27 Advice,
29 Instance,
31}
32
33impl std::fmt::Debug for Any {
34 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35 match self {
36 Self::Fixed => write!(f, "Fix"),
37 Self::Advice => write!(f, "Adv"),
38 Self::Instance => write!(f, "Ins"),
39 }
40 }
41}
42
43impl ColumnType for Any {
44 fn query_cell<F: Field, E: ExprBuilder<F>>(&self, index: usize, at: Rotation) -> E {
45 match self {
46 Any::Fixed => Fixed.query_cell(index, at),
47 Any::Advice => Advice.query_cell(index, at),
48 Any::Instance => Instance.query_cell(index, at),
49 }
50 }
51}
52
53impl ColumnType for Fixed {
54 fn query_cell<F: Field, E: ExprBuilder<F>>(&self, index: usize, at: Rotation) -> E {
55 E::FixedQuery::query_expr(index, at)
56 }
57}
58
59impl ColumnType for Advice {
60 fn query_cell<F: Field, E: ExprBuilder<F>>(&self, index: usize, at: Rotation) -> E {
61 E::AdviceQuery::query_expr(index, at)
62 }
63}
64
65impl ColumnType for Instance {
66 fn query_cell<F: Field, E: ExprBuilder<F>>(&self, index: usize, at: Rotation) -> E {
67 E::InstanceQuery::query_expr(index, at)
68 }
69}
70
71#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
73pub struct Column<C: ColumnType> {
74 index: usize,
75 column_type: C,
76}
77
78impl<C: ColumnType + std::fmt::Debug> std::fmt::Debug for Column<C> {
79 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80 write!(f, "{:?}:{}", self.column_type, self.index)
81 }
82}
83
84impl<C: ColumnType> Column<C> {
85 pub fn new(index: usize, column_type: C) -> Self {
87 Self { index, column_type }
88 }
89
90 pub fn index(&self) -> usize {
92 self.index
93 }
94
95 pub fn column_type(&self) -> &C {
97 &self.column_type
98 }
99
100 pub fn query_cell<F: Field, E: ExprBuilder<F>>(&self, at: Rotation) -> E {
102 self.column_type.query_cell(self.index, at)
103 }
104}
105
106impl From<Column<Fixed>> for Column<Any> {
107 fn from(value: Column<Fixed>) -> Self {
108 Self {
109 index: value.index,
110 column_type: Any::Fixed,
111 }
112 }
113}
114
115impl TryFrom<Column<Any>> for Column<Fixed> {
116 type Error = TableError;
117
118 fn try_from(value: Column<Any>) -> Result<Self, Self::Error> {
119 match value.column_type {
120 Any::Fixed => Ok(Self {
121 index: value.index,
122 column_type: Fixed,
123 }),
124 c => Err(TableError::ExpectedFixed(c)),
125 }
126 }
127}
128
129impl From<Column<Advice>> for Column<Any> {
130 fn from(value: Column<Advice>) -> Self {
131 Self {
132 index: value.index,
133 column_type: Any::Advice,
134 }
135 }
136}
137
138impl TryFrom<Column<Any>> for Column<Advice> {
139 type Error = TableError;
140
141 fn try_from(value: Column<Any>) -> Result<Self, Self::Error> {
142 match value.column_type {
143 Any::Advice => Ok(Self {
144 index: value.index,
145 column_type: Advice,
146 }),
147 c => Err(TableError::ExpectedAdvice(c)),
148 }
149 }
150}
151
152impl From<Column<Instance>> for Column<Any> {
153 fn from(value: Column<Instance>) -> Self {
154 Self {
155 index: value.index,
156 column_type: Any::Instance,
157 }
158 }
159}
160
161impl TryFrom<Column<Any>> for Column<Instance> {
162 type Error = TableError;
163
164 fn try_from(value: Column<Any>) -> Result<Self, Self::Error> {
165 match value.column_type {
166 Any::Instance => Ok(Self {
167 index: value.index,
168 column_type: Instance,
169 }),
170 c => Err(TableError::ExpectedInstance(c)),
171 }
172 }
173}
174
175#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
177pub struct Cell {
178 pub region_index: RegionIndex,
180 pub row_offset: usize,
182 pub column: Column<Any>,
184}
185
186pub type Rotation = i32;
188
189pub trait RotationExt {
191 fn cur() -> Self;
193
194 fn next() -> Self;
196
197 fn prev() -> Self;
199}
200
201impl RotationExt for Rotation {
202 fn cur() -> Self {
203 0
204 }
205
206 fn next() -> Self {
207 1
208 }
209
210 fn prev() -> Self {
211 -1
212 }
213}
214
215#[derive(Eq, Hash, PartialEq, Debug, Copy, Clone)]
217pub struct RegionIndex(usize);
218
219impl Deref for RegionIndex {
220 type Target = usize;
221
222 fn deref(&self) -> &Self::Target {
223 &self.0
224 }
225}
226
227impl From<usize> for RegionIndex {
228 fn from(value: usize) -> Self {
229 Self(value)
230 }
231}
232
233#[derive(Eq, Hash, PartialEq, Debug, Copy, Clone)]
235pub struct RegionStart(usize);
236
237impl Deref for RegionStart {
238 type Target = usize;
239
240 fn deref(&self) -> &Self::Target {
241 &self.0
242 }
243}
244
245impl From<usize> for RegionStart {
246 fn from(value: usize) -> Self {
247 Self(value)
248 }
249}
250
251#[derive(Error, Copy, Clone, Debug)]
253pub enum TableError {
254 #[error("Expected Any::Fixed. Got {0:?}")]
256 ExpectedFixed(Any),
257 #[error("Expected Any::Advice. Got {0:?}")]
259 ExpectedAdvice(Any),
260 #[error("Expected Any::Instance. Got {0:?}")]
262 ExpectedInstance(Any),
263}