trellis_testing/
resource_state.rs1use std::collections::BTreeSet;
2
3use trellis_core::{
4 ResourceCommand, ResourceCommandKind, ResourceTransitionPolicy, Revision, ScopeId,
5 TransactionId,
6};
7
8use crate::{HostStatusEvent, ResourceCommandContext};
9
10#[derive(Clone, Debug, Eq, PartialEq)]
12pub struct ResourceCommandRecord<C = ()> {
13 pub context: ResourceCommandContext,
15 pub transition: ResourceTransitionPolicy,
17 pub command: Option<C>,
19}
20
21impl<C: Clone> ResourceCommandRecord<C> {
22 pub(crate) fn from_command(
23 command: &ResourceCommand<C>,
24 transaction_id: TransactionId,
25 revision: Revision,
26 generation: u64,
27 ) -> Self {
28 Self {
29 context: ResourceCommandContext {
30 key: command.key().clone(),
31 scope: command.scope(),
32 transaction_id,
33 revision,
34 generation,
35 kind: resource_command_kind(command),
36 },
37 transition: resource_transition_policy(command),
38 command: retained_payload(command),
39 }
40 }
41}
42
43#[derive(Clone, Debug, Eq, PartialEq)]
45pub struct ResourceSnapshot<C = ()> {
46 pub owners: BTreeSet<ScopeId>,
48 pub is_open: bool,
50 pub open_count: usize,
52 pub close_count: usize,
54 pub replace_count: usize,
56 pub command_revision: Revision,
58 pub generation: u64,
60 pub last_transaction_id: TransactionId,
62 pub last_status_revision: Option<Revision>,
64 pub current_command: Option<C>,
66 pub injected_status: Option<HostStatusEvent>,
68 pub last_command: ResourceCommandRecord<C>,
70}
71
72impl<C: Clone> ResourceSnapshot<C> {
73 pub(crate) fn new(record: ResourceCommandRecord<C>) -> Self {
74 Self {
75 owners: BTreeSet::new(),
76 is_open: true,
77 open_count: 0,
78 close_count: 0,
79 replace_count: 0,
80 command_revision: record.context.revision,
81 generation: record.context.generation,
82 last_transaction_id: record.context.transaction_id,
83 last_status_revision: None,
84 current_command: record.command.clone(),
85 injected_status: None,
86 last_command: record,
87 }
88 }
89
90 pub(crate) fn record_command(&mut self, record: ResourceCommandRecord<C>) {
91 self.command_revision = record.context.revision;
92 self.generation = record.context.generation;
93 self.last_transaction_id = record.context.transaction_id;
94 self.current_command = record.command.clone();
95 self.last_command = record;
96 }
97}
98
99impl<C> ResourceSnapshot<C> {
100 pub(crate) fn command_context(&self) -> ResourceCommandContext {
101 self.last_command.context.clone()
102 }
103}
104
105fn retained_payload<C: Clone>(command: &ResourceCommand<C>) -> Option<C> {
106 match command {
107 ResourceCommand::Open { command, .. }
108 | ResourceCommand::Replace { command, .. }
109 | ResourceCommand::Refresh { command, .. } => Some(command.clone()),
110 ResourceCommand::Close { .. } => None,
111 }
112}
113
114fn resource_command_kind<C>(command: &ResourceCommand<C>) -> ResourceCommandKind {
115 match command {
116 ResourceCommand::Open { .. } => ResourceCommandKind::Open,
117 ResourceCommand::Close { .. } => ResourceCommandKind::Close,
118 ResourceCommand::Replace { .. } => ResourceCommandKind::Replace,
119 ResourceCommand::Refresh { .. } => ResourceCommandKind::Refresh,
120 }
121}
122
123fn resource_transition_policy<C>(command: &ResourceCommand<C>) -> ResourceTransitionPolicy {
124 match command {
125 ResourceCommand::Open { .. } => ResourceTransitionPolicy::Open,
126 ResourceCommand::Close { .. } => ResourceTransitionPolicy::Close,
127 ResourceCommand::Replace { .. } => ResourceTransitionPolicy::ReplaceAtomically,
128 ResourceCommand::Refresh { .. } => ResourceTransitionPolicy::Refresh,
129 }
130}