mina_node_testing/scenario/
id.rs1use std::str::FromStr;
2
3use serde::{Deserialize, Deserializer, Serialize};
4
5#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
6pub struct ScenarioId(String);
7
8#[derive(thiserror::Error, Debug)]
9pub enum ScenarioIdParseError {
10 #[error("scenario id can't contain upper-case characters")]
11 ContainsUpperCaseCharacters,
12 #[error("scenario id must match pattern /[a-z0-9_-]*/")]
13 AcceptedPatternMismatch,
14}
15
16#[cfg(feature = "scenario-generators")]
17impl From<crate::scenarios::Scenarios> for ScenarioId {
18 fn from(value: crate::scenarios::Scenarios) -> Self {
19 Self(value.to_str().to_owned())
20 }
21}
22
23impl std::fmt::Display for ScenarioId {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 self.0.fmt(f)
26 }
27}
28
29impl FromStr for ScenarioId {
30 type Err = ScenarioIdParseError;
31
32 fn from_str(s: &str) -> Result<Self, Self::Err> {
33 for c in s.chars() {
34 if c.is_ascii_uppercase() {
35 return Err(ScenarioIdParseError::ContainsUpperCaseCharacters);
36 }
37 if c.is_ascii_lowercase() || c.is_ascii_digit() || c == '-' || c == '_' {
38 continue;
39 }
40 return Err(ScenarioIdParseError::AcceptedPatternMismatch);
41 }
42 Ok(Self(s.to_owned()))
43 }
44}
45
46impl<'de> Deserialize<'de> for ScenarioId {
47 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
48 where
49 D: Deserializer<'de>,
50 {
51 let s: &str = Deserialize::deserialize(deserializer)?;
52
53 Self::from_str(s).map_err(serde::de::Error::custom)
54 }
55}