Я хочу иметь возможность записать цвет как шестнадцатеричный объект json и затем десериализовать его во внутреннее значение типа u64
моего перечисления Color
.
На данный момент у меня есть перечисление, похожее на это:
#[derive(Deserialize, Serialize)]
pub enum Color {
Red,
Green,
Blue,
Custom(u64)
}
, которое я затем использую в структуре, похожей на это:
pub struct Config {
#[serde(rename = "borderColor", deserialize_with = "color_deserialize")]
pub border_color: Color,
}
Пользовательская функция десериализации:
fn color_deserialize<'de, D>(desierializer: D) -> Result<Color, D::Error>
where
D: Deserializer<'de>
{
use serde::de::Error;
let col = match Color::deserialize(desierializer) {
Ok(col) => col,
Err(e) => return Err(format!("Failed to deserilize color: {}", e)).map_err(Error::custom)
};
match col {
Color::Custom(x) => {
let x_str = &x.to_string();
let without_prefix = x_str.trim_start_matches("#");
let res = match u64::from_str_radix(without_prefix, 16) {
Ok(res) => res,
Err(e) => return Err(format!("Failed to deserialize color: {}", e)).map_err(Error::custom)
};
Ok(Color::Custom(res))
},
x => Ok(col)
}
}
Мое понимание проблемы сейчас заключается в том, что производное Deserialize
сначала отображает значение json в соответствии с типом перечисления (которое является u64), прежде чем я пытаюсь преобразовать его в десятичное , Поэтому из-за этого он сломается, если представление json будет строкой, а не числом.
Как я могу сохранить свой вариант с внутренним типом u64
, но представить цвет как шестнадцатеричный в json