use std::str::FromStr;
use std::{collections::HashMap, num::NonZeroU16};
use quil_rs::Program;
use crate::{executable::Parameters, qvm::run_program};
use super::{http::AddressRequest, Error, QvmResultData};
use super::{Client, QvmOptions};
#[derive(Debug, Clone, PartialEq)]
pub(crate) struct Execution {
program: Program,
}
impl Execution {
pub(crate) fn new(quil: &str) -> Result<Self, Error> {
let program = Program::from_str(quil).map_err(Error::Parsing)?;
Ok(Self { program })
}
pub(crate) async fn run<C: Client + ?Sized>(
&self,
shots: NonZeroU16,
addresses: HashMap<String, AddressRequest>,
params: &Parameters,
client: &C,
) -> Result<QvmResultData, Error> {
run_program(
&self.program,
shots,
addresses,
params,
None,
None,
None,
client,
&QvmOptions::default(),
)
.await
}
}
#[cfg(test)]
mod describe_execution {
use std::{collections::HashMap, num::NonZeroU16};
use super::{Execution, Parameters};
use crate::{client::Qcs, qvm};
fn qvm_client() -> qvm::http::HttpClient {
let qcs = Qcs::load();
qvm::http::HttpClient::from(&qcs)
}
#[tokio::test]
async fn it_errs_on_excess_parameters() {
let exe = Execution::new("DECLARE ro BIT").unwrap();
let mut params = Parameters::new();
params.insert("doesnt_exist".into(), vec![0.0]);
let result = exe
.run(
NonZeroU16::new(1).expect("value is non-zero"),
HashMap::new(),
¶ms,
&qvm_client(),
)
.await;
if let Err(e) = result {
assert!(e.to_string().contains("doesnt_exist"));
} else {
panic!("Expected an error but got none.");
}
}
#[tokio::test]
async fn it_errors_when_any_param_is_the_wrong_size() {
let exe = Execution::new("DECLARE ro BIT[2]").unwrap();
let mut params = Parameters::new();
params.insert("ro".into(), vec![0.0]);
let result = exe
.run(
NonZeroU16::new(1).expect("value is non-zero"),
HashMap::new(),
¶ms,
&qvm_client(),
)
.await;
if let Err(e) = result {
let err_string = e.to_string();
assert!(err_string.contains("ro"));
assert!(err_string.contains('1'));
assert!(err_string.contains('2'));
} else {
panic!("Expected an error but got none.");
}
}
}