bootstrap/core/config/toml/
change_id.rs

1use serde::{Deserialize, Deserializer};
2use serde_derive::Deserialize;
3
4/// This enum is used for deserializing change IDs from TOML, allowing both numeric values and the string `"ignore"`.
5#[derive(Clone, Debug, PartialEq)]
6pub enum ChangeId {
7    Ignore,
8    Id(usize),
9}
10
11/// Since we use `#[serde(deny_unknown_fields)]` on `TomlConfig`, we need a wrapper type
12/// for the "change-id" field to parse it even if other fields are invalid. This ensures
13/// that if deserialization fails due to other fields, we can still provide the changelogs
14/// to allow developers to potentially find the reason for the failure in the logs..
15#[derive(Deserialize, Default)]
16pub(crate) struct ChangeIdWrapper {
17    #[serde(alias = "change-id", default, deserialize_with = "deserialize_change_id")]
18    pub(crate) inner: Option<ChangeId>,
19}
20
21fn deserialize_change_id<'de, D: Deserializer<'de>>(
22    deserializer: D,
23) -> Result<Option<ChangeId>, D::Error> {
24    let value = toml::Value::deserialize(deserializer)?;
25    Ok(match value {
26        toml::Value::String(s) if s == "ignore" => Some(ChangeId::Ignore),
27        toml::Value::Integer(i) => Some(ChangeId::Id(i as usize)),
28        _ => {
29            return Err(serde::de::Error::custom(
30                "expected \"ignore\" or an integer for change-id",
31            ));
32        }
33    })
34}