A library for writing host-specific, single-binary configuration management and deployment tools
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

74 lines
2.2 KiB

  1. use super::{Add, AddGeneric, AddResult, AddableResource, Runnable, SymbolRunner};
  2. use crate::{ImplementationBuilder, ResourceLocator};
  3. use async_trait::async_trait;
  4. use slog::{debug, o, trace, Logger};
  5. use std::fmt::Debug;
  6. use std::marker::PhantomData;
  7. use std::rc::{Rc, Weak};
  8. #[derive(Debug)]
  9. pub struct Realizer<SR, L, B, S> {
  10. symbol_runner: Rc<SR>,
  11. outer: Weak<S>,
  12. phantom: PhantomData<(L, B)>,
  13. }
  14. impl<SR, L, B, S> Realizer<SR, L, B, S> {
  15. pub fn new(symbol_runner: Rc<SR>, outer: Weak<S>) -> Self {
  16. Self {
  17. symbol_runner,
  18. outer,
  19. phantom: PhantomData::default(),
  20. }
  21. }
  22. }
  23. #[async_trait(?Send)]
  24. impl<R, SR, L, B, S> Add<R> for Realizer<SR, L, B, S>
  25. where
  26. R: AddableResource,
  27. SR: SymbolRunner,
  28. L: ResourceLocator<R>,
  29. B: ImplementationBuilder<R>,
  30. <B as ImplementationBuilder<R>>::Implementation: Runnable + Debug,
  31. S: AddGeneric<B::Prerequisites> + AddGeneric<<L as ResourceLocator<R>>::Prerequisites>,
  32. {
  33. async fn add(&self, logger: &Rc<Logger>, resource: Rc<R>, force_run: bool) -> AddResult<R> {
  34. let setup = self.outer.upgrade().unwrap();
  35. let logger = Rc::new(logger.new(o!("resource" => format!("{resource:?}"))));
  36. trace!(logger, "(force_run is {})", force_run);
  37. let (location, location_prereqs) = L::locate(&resource);
  38. trace!(logger, "Adding location prereqs ...");
  39. let (_, location_prereqs_did_run) = (*setup)
  40. .add_generic(&logger, location_prereqs, false)
  41. .await?;
  42. trace!(
  43. logger,
  44. "Location prereqs did_run: {}",
  45. location_prereqs_did_run
  46. );
  47. trace!(logger, "Adding implementation prereqs ...");
  48. let (prereqs, prereqs_did_run) = (*setup)
  49. .add_generic(&logger, B::prerequisites(&resource), false)
  50. .await?;
  51. trace!(
  52. logger,
  53. "Implementation prereqs did_run: {}",
  54. prereqs_did_run
  55. );
  56. trace!(logger, "Running implementation ...");
  57. let implementation = B::create(&resource, &location, prereqs);
  58. let did_run = implementation
  59. .run(
  60. &*self.symbol_runner,
  61. &logger,
  62. force_run || location_prereqs_did_run || prereqs_did_run,
  63. )
  64. .await?;
  65. debug!(logger, "done.");
  66. Ok((location, did_run))
  67. }
  68. }