ledger_sim/drivers/
mod.rs1use core::fmt::Debug;
4
5use async_trait::async_trait;
6use strum::{Display, EnumString, EnumVariantNames};
7
8use crate::Options;
9
10mod local;
11pub use local::{LocalDriver, LocalHandle};
12
13mod docker;
14pub use docker::{DockerDriver, DockerHandle};
15
16#[derive(Copy, Clone, PartialEq, Debug, clap::ValueEnum, EnumString, EnumVariantNames, Display)]
18#[strum(serialize_all = "lowercase")]
19pub enum DriverMode {
20 Local,
22 Docker,
24}
25
26#[async_trait]
28pub trait Driver {
29 type Handle: Debug;
30
31 async fn run(&self, app: &str, opts: Options) -> anyhow::Result<Self::Handle>;
33
34 async fn wait(&self, handle: &mut Self::Handle) -> anyhow::Result<()>;
36
37 async fn exit(&self, mut handle: Self::Handle) -> anyhow::Result<()>;
39}
40
41pub enum GenericDriver {
44 Local(LocalDriver),
45 Docker(DockerDriver),
46}
47
48impl GenericDriver {
49 pub fn new(mode: DriverMode) -> Result<Self, anyhow::Error> {
51 let d = match mode {
52 DriverMode::Local => Self::Local(LocalDriver::new()),
53 DriverMode::Docker => Self::Docker(DockerDriver::new()?),
54 };
55 Ok(d)
56 }
57}
58
59#[derive(Debug)]
61pub enum GenericHandle {
62 Local(LocalHandle),
63 Docker(DockerHandle),
64}
65
66#[async_trait]
69impl Driver for GenericDriver {
70 type Handle = GenericHandle;
71
72 async fn run(&self, app: &str, opts: Options) -> anyhow::Result<Self::Handle> {
73 let h = match self {
74 GenericDriver::Local(d) => d.run(app, opts).await.map(GenericHandle::Local)?,
75 GenericDriver::Docker(d) => d.run(app, opts).await.map(GenericHandle::Docker)?,
76 };
77
78 Ok(h)
79 }
80
81 async fn wait(&self, handle: &mut Self::Handle) -> anyhow::Result<()> {
82 match (self, handle) {
83 (GenericDriver::Local(d), GenericHandle::Local(h)) => d.wait(h).await?,
84 (GenericDriver::Docker(d), GenericHandle::Docker(h)) => d.wait(h).await?,
85 _ => panic!("driver/handler mismatch"),
86 };
87 Ok(())
88 }
89
90 async fn exit(&self, handle: Self::Handle) -> anyhow::Result<()> {
91 match (self, handle) {
92 (GenericDriver::Local(d), GenericHandle::Local(h)) => d.exit(h).await?,
93 (GenericDriver::Docker(d), GenericHandle::Docker(h)) => d.exit(h).await?,
94 _ => panic!("driver/handler mismatch"),
95 };
96 Ok(())
97 }
98}