use super::metadata::Column as ColumnMetadata;
use crate::plonk;
use halo2_middleware::circuit::Any;
pub use halo2_middleware::circuit::ColumnMid as Column;
use std::{
collections::HashMap,
fmt::{self, Debug},
};
#[derive(Debug, Clone)]
pub(super) struct DebugColumn {
column_type: Any,
index: usize,
annotation: String,
}
impl From<(Column, Option<&HashMap<Column, String>>)> for DebugColumn {
fn from(info: (Column, Option<&HashMap<Column, String>>)) -> Self {
DebugColumn {
column_type: info.0.column_type,
index: info.0.index,
annotation: info
.1
.and_then(|map| map.get(&info.0))
.cloned()
.unwrap_or_default(),
}
}
}
impl fmt::Display for DebugColumn {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Column('{:?}', {} - {})",
self.column_type, self.index, self.annotation
)
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub struct VirtualCell {
name: String,
pub(super) column: Column,
pub(super) rotation: i32,
}
impl From<(Column, i32)> for VirtualCell {
fn from((column, rotation): (Column, i32)) -> Self {
VirtualCell {
name: "".to_string(),
column,
rotation,
}
}
}
impl<S: AsRef<str>> From<(S, Column, i32)> for VirtualCell {
fn from((name, column, rotation): (S, Column, i32)) -> Self {
VirtualCell {
name: name.as_ref().to_string(),
column,
rotation,
}
}
}
impl From<plonk::VirtualCell> for VirtualCell {
fn from(c: plonk::VirtualCell) -> Self {
VirtualCell {
name: "".to_string(),
column: c.column.into(),
rotation: c.rotation.0,
}
}
}
impl fmt::Display for VirtualCell {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}@{}", self.column, self.rotation)?;
if !self.name.is_empty() {
write!(f, "({})", self.name.as_str())?;
}
Ok(())
}
}
#[derive(Clone, Debug)]
pub(super) struct DebugVirtualCell {
name: String,
column: DebugColumn,
rotation: i32,
}
impl From<(&VirtualCell, Option<&HashMap<Column, String>>)> for DebugVirtualCell {
fn from(info: (&VirtualCell, Option<&HashMap<Column, String>>)) -> Self {
DebugVirtualCell {
name: info.0.name.clone(),
column: DebugColumn::from((info.0.column, info.1)),
rotation: info.0.rotation,
}
}
}
impl fmt::Display for DebugVirtualCell {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}@{}", self.column, self.rotation)?;
if !self.name.is_empty() {
write!(f, "({})", self.name)?;
}
Ok(())
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Gate {
pub(super) index: usize,
pub(super) name: String,
}
impl fmt::Display for Gate {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Gate {} ('{}')", self.index, self.name.as_str())
}
}
impl<S: AsRef<str>> From<(usize, S)> for Gate {
fn from((index, name): (usize, S)) -> Self {
Gate {
index,
name: name.as_ref().to_string(),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Constraint {
pub(super) gate: Gate,
pub(super) index: usize,
pub(super) name: String,
}
impl fmt::Display for Constraint {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Constraint {}{} in gate {} ('{}')",
self.index,
if self.name.is_empty() {
String::new()
} else {
format!(" ('{}')", self.name.as_str())
},
self.gate.index,
self.gate.name,
)
}
}
impl<S: AsRef<str>> From<(Gate, usize, S)> for Constraint {
fn from((gate, index, name): (Gate, usize, S)) -> Self {
Constraint {
gate,
index,
name: name.as_ref().to_string(),
}
}
}
#[derive(Clone)]
pub struct Region {
pub(super) index: usize,
pub(super) name: String,
pub(super) column_annotations: Option<HashMap<ColumnMetadata, String>>,
}
impl Region {
pub(crate) fn get_column_annotation(&self, metadata: ColumnMetadata) -> Option<String> {
self.column_annotations
.as_ref()
.and_then(|map| map.get(&metadata).cloned())
}
}
impl PartialEq for Region {
fn eq(&self, other: &Self) -> bool {
self.index == other.index && self.name == other.name
}
}
impl Eq for Region {}
impl Debug for Region {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Region {} ('{}')", self.index, self.name)
}
}
impl fmt::Display for Region {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Region {} ('{}')", self.index, self.name.as_str())
}
}
impl From<(usize, String)> for Region {
fn from((index, name): (usize, String)) -> Self {
Region {
index,
name,
column_annotations: None,
}
}
}
impl From<(usize, &str)> for Region {
fn from((index, name): (usize, &str)) -> Self {
Region {
index,
name: name.to_owned(),
column_annotations: None,
}
}
}
impl From<(usize, String, HashMap<ColumnMetadata, String>)> for Region {
fn from((index, name, annotations): (usize, String, HashMap<ColumnMetadata, String>)) -> Self {
Region {
index,
name,
column_annotations: Some(annotations),
}
}
}
impl From<(usize, &str, HashMap<ColumnMetadata, String>)> for Region {
fn from((index, name, annotations): (usize, &str, HashMap<ColumnMetadata, String>)) -> Self {
Region {
index,
name: name.to_owned(),
column_annotations: Some(annotations),
}
}
}