use std::fmt::Debug;
use crate::instruction::GateSignature;
use super::{CalibrationSource, InstructionIndex};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SourceMap<SourceIndex, TargetIndex> {
pub(crate) entries: Vec<SourceMapEntry<SourceIndex, TargetIndex>>,
}
impl<SourceIndex, TargetIndex> SourceMap<SourceIndex, TargetIndex> {
pub fn new(entries: Vec<SourceMapEntry<SourceIndex, TargetIndex>>) -> Self {
Self { entries }
}
pub fn list_sources<QueryIndex>(&self, target_index: &QueryIndex) -> Vec<&SourceIndex>
where
TargetIndex: SourceMapIndexable<QueryIndex>,
{
self.entries
.iter()
.filter(|&entry| entry.target_location().contains(target_index))
.map(SourceMapEntry::source_location)
.collect()
}
pub fn list_targets<QueryIndex>(&self, source_index: &QueryIndex) -> Vec<&TargetIndex>
where
SourceIndex: SourceMapIndexable<QueryIndex>,
{
self.entries
.iter()
.filter(|entry| entry.source_location().contains(source_index))
.map(SourceMapEntry::target_location)
.collect()
}
}
impl<SourceIndex, TargetIndex> Default for SourceMap<SourceIndex, TargetIndex> {
fn default() -> Self {
Self {
entries: Vec::new(),
}
}
}
impl<SourceIndex, TargetIndex> SourceMap<SourceIndex, TargetIndex> {
pub fn entries(&self) -> &[SourceMapEntry<SourceIndex, TargetIndex>] {
&self.entries
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SourceMapEntry<SourceIndex, TargetIndex> {
pub(crate) source_location: SourceIndex,
pub(crate) target_location: TargetIndex,
}
impl<SourceIndex, TargetIndex> SourceMapEntry<SourceIndex, TargetIndex> {
pub fn new(source_location: SourceIndex, target_location: TargetIndex) -> Self {
Self {
source_location,
target_location,
}
}
pub fn source_location(&self) -> &SourceIndex {
&self.source_location
}
pub fn target_location(&self) -> &TargetIndex {
&self.target_location
}
}
pub trait SourceMapIndexable<Index> {
fn contains(&self, other: &Index) -> bool;
}
impl SourceMapIndexable<InstructionIndex> for InstructionIndex {
fn contains(&self, other: &InstructionIndex) -> bool {
self == other
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum ExpansionResult<R> {
Unmodified(InstructionIndex),
Rewritten(R),
}
impl<R> SourceMapIndexable<InstructionIndex> for ExpansionResult<R>
where
R: SourceMapIndexable<InstructionIndex>,
{
fn contains(&self, other: &InstructionIndex) -> bool {
match self {
Self::Unmodified(index) => index == other,
Self::Rewritten(rewrite) => rewrite.contains(other),
}
}
}
impl<R> SourceMapIndexable<CalibrationSource> for ExpansionResult<R>
where
R: SourceMapIndexable<CalibrationSource>,
{
fn contains(&self, other: &CalibrationSource) -> bool {
if let Self::Rewritten(rewrite) = self {
rewrite.contains(other)
} else {
false
}
}
}
impl<'a, R> SourceMapIndexable<GateSignature<'a>> for ExpansionResult<R>
where
R: SourceMapIndexable<GateSignature<'a>>,
{
fn contains(&self, other: &GateSignature<'a>) -> bool {
if let Self::Rewritten(rewrite) = self {
rewrite.contains(other)
} else {
false
}
}
}