Skip to content

Commit

Permalink
Deserialize numbers from string
Browse files Browse the repository at this point in the history
  • Loading branch information
mstyura authored and yyaroshevich committed Jan 4, 2024
1 parent 020cd74 commit 5e112ec
Showing 1 changed file with 30 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pub enum ConstraintExpression {
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
pub struct Variant {
pub name: String,
#[serde(deserialize_with = "deserialize_number_from_string")]
pub weight: u16,
pub payload: Option<HashMap<String, String>>,
pub overrides: Option<Vec<VariantOverride>>,
Expand Down Expand Up @@ -137,6 +138,25 @@ pub struct MetricsBucket {
pub toggles: HashMap<String, ToggleMetrics>,
}

fn deserialize_number_from_string<'de, T, D>(deserializer: D) -> Result<T, D::Error>
where
D: serde::Deserializer<'de>,
T: std::str::FromStr + serde::Deserialize<'de>,
<T as std::str::FromStr>::Err: std::fmt::Display,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum StringOrInt<T> {
String(String),
Number(T),
}

match StringOrInt::<T>::deserialize(deserializer)? {
StringOrInt::String(s) => s.parse::<T>().map_err(serde::de::Error::custom),
StringOrInt::Number(i) => Ok(i),
}
}

#[cfg(test)]
mod tests {
use super::Registration;
Expand Down Expand Up @@ -249,6 +269,16 @@ mod tests {
Ok(())
}

#[test]
fn test_parse_variant_with_str_weight() -> Result<(), serde_json::Error> {
let data = r#"
{"name":"Foo","weight":"50","payload":{"type":"string","value":"bar"}}
"#;
let parsed: super::Variant = serde_json::from_str(data)?;
assert_eq!(50, parsed.weight);
Ok(())
}

#[test]
fn test_registration_customisation() {
Registration {
Expand Down

0 comments on commit 5e112ec

Please sign in to comment.