pub trait Quil: std::fmt::Debug {
fn to_quil(&self) -> Result<String, ToQuilError> {
let mut buffer = String::new();
self.write(&mut buffer, false)?;
Ok(buffer)
}
fn to_quil_or_debug(&self) -> String {
let mut buffer = String::new();
let _ = self.write(&mut buffer, true);
buffer
}
fn write(
&self,
writer: &mut impl std::fmt::Write,
fall_back_to_debug: bool,
) -> Result<(), ToQuilError>;
}
pub(crate) const INDENT: &str = " ";
pub type ToQuilResult<T> = Result<T, ToQuilError>;
#[derive(Debug, thiserror::Error, PartialEq)]
#[non_exhaustive]
pub enum ToQuilError {
#[error("Failed to write Quil: {0}")]
FormatError(#[from] std::fmt::Error),
#[error("Label has not yet been resolved")]
UnresolvedLabelPlaceholder,
#[error("Qubit has not yet been resolved")]
UnresolvedQubitPlaceholder,
}
pub(crate) fn write_join_quil<'i, I, T>(
writer: &mut impl std::fmt::Write,
fall_back_to_debug: bool,
values: I,
joiner: &str,
prefix: &str,
) -> Result<(), ToQuilError>
where
I: IntoIterator<Item = &'i T>,
T: Quil + 'i,
{
let mut iter = values.into_iter();
if let Some(first) = iter.next() {
write!(writer, "{prefix}")?;
first.write(writer, fall_back_to_debug)?;
for value in iter {
write!(writer, "{joiner}{prefix}")?;
value.write(writer, fall_back_to_debug)?;
}
}
Ok(())
}