1use std::{fmt, str::FromStr};
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
7#[serde(rename_all = "lowercase")]
8pub enum Tier {
9 Read,
11 Mutate,
13 Destructive,
15}
16
17impl Tier {
18 #[must_use]
20 pub const fn is_mutating(self) -> bool {
21 matches!(self, Self::Mutate | Self::Destructive)
22 }
23
24 #[must_use]
26 pub const fn as_str(self) -> &'static str {
27 match self {
28 Self::Read => "read",
29 Self::Mutate => "mutate",
30 Self::Destructive => "destructive",
31 }
32 }
33}
34
35impl fmt::Display for Tier {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 f.write_str(self.as_str())
38 }
39}
40
41impl FromStr for Tier {
42 type Err = ParseTierError;
43
44 fn from_str(value: &str) -> Result<Self, Self::Err> {
45 match value {
46 "read" => Ok(Self::Read),
47 "mutate" => Ok(Self::Mutate),
48 "destructive" => Ok(Self::Destructive),
49 other => Err(ParseTierError {
50 value: other.to_owned(),
51 }),
52 }
53 }
54}
55
56#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
58#[error("invalid tier {value:?}: must be one of read, mutate, destructive")]
59pub struct ParseTierError {
60 value: String,
61}