systemd-transient 0.1.3

Start transient systemd services using dbus, just like systemd-run.
Documentation
use crate::error::SystemdTransientError;
use crate::{SystemdTransientManager, TransientUnitHandle, UnitExit, UnitProperty};

pub(crate) struct Opts {
  pub(crate) name: String,
  pub(crate) props: Vec<UnitProperty>,
}

pub struct ReusableTransientUnit {
  pub(crate) opts: Opts,
  pub(crate) unit_handle: Option<TransientUnitHandle>,
  pub(crate) systemd_manager: SystemdTransientManager,
}

impl ReusableTransientUnit {
  pub async fn start(&mut self) -> Result<(), SystemdTransientError> {
    if self.unit_handle.is_some() {
      return Err(SystemdTransientError::UnitAlreadyRunning {
        name: self.opts.name.to_owned(),
      });
    }

    let handle = self
      .systemd_manager
      .start(self.opts.name.to_owned(), self.opts.props.to_vec())
      .await?;

    self.unit_handle = Some(handle);

    Ok(())
  }

  pub async fn stop(&mut self) -> Result<(), SystemdTransientError> {
    match self.unit_handle.take() {
      Some(handle) => handle.stop().await?,
      None => {
        return Err(SystemdTransientError::UnitNotRunning {
          name: self.opts.name.to_owned(),
        });
      }
    };

    Ok(())
  }

  pub async fn wait_for_exit(&self) -> Result<UnitExit, SystemdTransientError> {
    let handle =
      self
        .unit_handle
        .as_ref()
        .ok_or_else(|| SystemdTransientError::UnitNotRunning {
          name: self.opts.name.to_owned(),
        })?;

    handle.wait_for_exit().await
  }
}