olai_stack_state/error.rs
1//! The crate's [`Error`].
2
3/// What can go wrong reading or writing the [`Store`](crate::Store).
4#[derive(Debug, thiserror::Error)]
5pub enum Error {
6 /// SQLite failed.
7 #[error("state store: {0}")]
8 Sqlite(#[from] rusqlite::Error),
9 /// The store was written by a newer version than this one understands.
10 #[error(
11 "state store schema version {found} is newer than this version supports ({supported}); \
12 upgrade trestle"
13 )]
14 UnsupportedVersion {
15 /// The store's schema version.
16 found: u32,
17 /// The newest version this crate reads.
18 supported: u32,
19 },
20 /// A name is not valid (see [`is_valid_name`](olai_stack_topology::workspace::is_valid_name)).
21 #[error(
22 "`{0}` is not a valid name: use lowercase letters, digits and dashes, starting with a letter"
23 )]
24 InvalidName(String),
25 /// Something already exists under that name.
26 #[error("{kind} `{name}` already exists")]
27 Duplicate {
28 /// What kind of thing (`workspace`, `environment`).
29 kind: &'static str,
30 /// Its name.
31 name: String,
32 },
33 /// No such thing.
34 #[error("no {kind} `{id}`")]
35 NotFound {
36 /// What kind of thing.
37 kind: &'static str,
38 /// Its id or name.
39 id: String,
40 },
41 /// A workspace or environment can't be renamed (or its mesh changed) while it has
42 /// instances: their compose projects, volumes, hostnames and mesh network are named after
43 /// it, so the change would strand what Docker already holds under the old name.
44 #[error(
45 "{kind} `{name}` has {instances} instance{}: remove {} first",
46 if *instances == 1 { "" } else { "s" },
47 if *instances == 1 { "it" } else { "them" }
48 )]
49 HasInstances {
50 /// What kind of thing (`workspace`, `environment`).
51 kind: &'static str,
52 /// Its name.
53 name: String,
54 /// How many instances it has.
55 instances: usize,
56 },
57 /// Every slot is leased.
58 #[error("no free slot: the host runs at most {} instances", olai_stack_topology::MAX_SLOT + 1)]
59 SlotsExhausted,
60 /// An environment manifest didn't (de)serialize.
61 #[error(transparent)]
62 Manifest(#[from] olai_stack_topology::ManifestError),
63 /// A workspace manifest didn't (de)serialize.
64 #[error(transparent)]
65 Workspace(#[from] olai_stack_topology::WorkspaceError),
66 /// A stored JSON column didn't (de)serialize.
67 #[error("state store JSON: {0}")]
68 Json(#[from] serde_json::Error),
69 /// Reading or writing an import/export directory failed.
70 #[error("{path}: {source}")]
71 Io {
72 /// The file or directory.
73 path: std::path::PathBuf,
74 /// The I/O error.
75 #[source]
76 source: std::io::Error,
77 },
78 /// An export can't be written as asked.
79 #[error("can't export: {0}")]
80 Export(String),
81}
82
83impl Error {
84 pub(crate) fn io(path: impl Into<std::path::PathBuf>, source: std::io::Error) -> Self {
85 Error::Io {
86 path: path.into(),
87 source,
88 }
89 }
90}
91
92/// The crate's result type.
93pub type Result<T, E = Error> = std::result::Result<T, E>;