crate_seq_ledger/state.rs
1//! State-machine transitions for [`LedgerStatus`].
2
3use crate::{CrateSeqLedger, Error, LedgerStatus};
4
5impl CrateSeqLedger {
6 /// Marks `version` as [`LedgerStatus::Published`].
7 ///
8 /// Permitted source states: [`LedgerStatus::Pending`], [`LedgerStatus::Skipped`].
9 ///
10 /// # Errors
11 ///
12 /// Returns [`Error::VersionNotFound`] if no entry exists for `version`.
13 /// Returns [`Error::InvalidTransition`] if the entry is [`LedgerStatus::Published`]
14 /// or [`LedgerStatus::Yanked`].
15 pub fn mark_published(&mut self, version: &semver::Version) -> Result<(), Error> {
16 let entry = self
17 .entries
18 .iter_mut()
19 .find(|e| &e.version == version)
20 .ok_or_else(|| Error::VersionNotFound(version.clone()))?;
21
22 match entry.status {
23 LedgerStatus::Pending | LedgerStatus::Skipped => {
24 entry.status = LedgerStatus::Published;
25 Ok(())
26 }
27 LedgerStatus::Published => Err(Error::InvalidTransition(
28 version.clone(),
29 "published",
30 "published",
31 )),
32 LedgerStatus::Yanked => Err(Error::InvalidTransition(
33 version.clone(),
34 "yanked",
35 "published",
36 )),
37 }
38 }
39
40 /// Marks `version` as [`LedgerStatus::Skipped`].
41 ///
42 /// Permitted source states: [`LedgerStatus::Pending`], [`LedgerStatus::Skipped`],
43 /// [`LedgerStatus::Yanked`].
44 ///
45 /// # Errors
46 ///
47 /// Returns [`Error::VersionNotFound`] if no entry exists for `version`.
48 /// Returns [`Error::InvalidTransition`] if the entry is [`LedgerStatus::Published`].
49 pub fn mark_skipped(&mut self, version: &semver::Version) -> Result<(), Error> {
50 let entry = self
51 .entries
52 .iter_mut()
53 .find(|e| &e.version == version)
54 .ok_or_else(|| Error::VersionNotFound(version.clone()))?;
55
56 match entry.status {
57 LedgerStatus::Published => Err(Error::InvalidTransition(
58 version.clone(),
59 "published",
60 "skipped",
61 )),
62 LedgerStatus::Pending | LedgerStatus::Skipped | LedgerStatus::Yanked => {
63 entry.status = LedgerStatus::Skipped;
64 Ok(())
65 }
66 }
67 }
68
69 /// Marks `version` as [`LedgerStatus::Yanked`].
70 ///
71 /// Permitted source state: [`LedgerStatus::Published`].
72 ///
73 /// # Errors
74 ///
75 /// Returns [`Error::VersionNotFound`] if no entry exists for `version`.
76 /// Returns [`Error::InvalidTransition`] if the entry is not [`LedgerStatus::Published`].
77 pub fn mark_yanked(&mut self, version: &semver::Version) -> Result<(), Error> {
78 let entry = self
79 .entries
80 .iter_mut()
81 .find(|e| &e.version == version)
82 .ok_or_else(|| Error::VersionNotFound(version.clone()))?;
83
84 match entry.status {
85 LedgerStatus::Published => {
86 entry.status = LedgerStatus::Yanked;
87 Ok(())
88 }
89 LedgerStatus::Pending => Err(Error::InvalidTransition(
90 version.clone(),
91 "pending",
92 "yanked",
93 )),
94 LedgerStatus::Skipped => Err(Error::InvalidTransition(
95 version.clone(),
96 "skipped",
97 "yanked",
98 )),
99 LedgerStatus::Yanked => Err(Error::InvalidTransition(
100 version.clone(),
101 "yanked",
102 "yanked",
103 )),
104 }
105 }
106}