Skip to content

Commit cb7f17e

Browse files
committed
Disallow certain values for IDs
We don't want users to name their proceses `all` or whatever as it'll break things, so let's prohibit it. I've currently prohibited empty strings, `all` and `annual` (could cause issues if a user names a season this). Closes #548.
1 parent e6a158c commit cb7f17e

1 file changed

Lines changed: 27 additions & 3 deletions

File tree

src/id.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ impl<T> IDLike for T where
1515

1616
macro_rules! define_id_type {
1717
($name:ident) => {
18-
#[derive(
19-
Clone, std::hash::Hash, PartialEq, Eq, serde::Deserialize, Debug, serde::Serialize,
20-
)]
18+
#[derive(Clone, std::hash::Hash, PartialEq, Eq, Debug, serde::Serialize)]
2119
/// An ID type (e.g. `AgentID`, `CommodityID`, etc.)
2220
pub struct $name(pub std::rc::Rc<str>);
2321

@@ -45,6 +43,32 @@ macro_rules! define_id_type {
4543
}
4644
}
4745

46+
impl<'de> serde::Deserialize<'de> for $name {
47+
fn deserialize<D>(deserialiser: D) -> std::result::Result<Self, D::Error>
48+
where
49+
D: serde::Deserializer<'de>,
50+
{
51+
use serde::de::Error;
52+
53+
let id: String = serde::Deserialize::deserialize(deserialiser)?;
54+
let id = id.trim();
55+
if id.is_empty() {
56+
return Err(D::Error::custom("IDs cannot be empty"));
57+
}
58+
59+
const FORBIDDEN_IDS: [&str; 2] = ["all", "annual"];
60+
for forbidden in FORBIDDEN_IDS.iter() {
61+
if id.eq_ignore_ascii_case(forbidden) {
62+
return Err(D::Error::custom(format!(
63+
"'{id}' is an invalid value for an ID"
64+
)));
65+
}
66+
}
67+
68+
Ok(id.into())
69+
}
70+
}
71+
4872
impl $name {
4973
/// Create a new ID from a string slice
5074
pub fn new(id: &str) -> Self {

0 commit comments

Comments
 (0)