use std::fmt; use serde::de; use crate::{AtError, AtResult, Parse}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum NumWorkers { Default, Manual(usize), } impl Parse for NumWorkers { fn parse(string: &str) -> AtResult { match string { "default" => Ok(NumWorkers::Default), string => match string.parse::() { Ok(val) => Ok(NumWorkers::Manual(val)), Err(_) => Err(InvalidValue! { expected: "a positive integer", got: string, }), }, } } } impl<'de> de::Deserialize<'de> for NumWorkers { fn deserialize(deserializer: D) -> Result where D: de::Deserializer<'de>, { struct NumWorkersVisitor; impl<'de> de::Visitor<'de> for NumWorkersVisitor { type Value = NumWorkers; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { let msg = "Either \"default\" or a string containing an integer > 0"; formatter.write_str(msg) } fn visit_str(self, value: &str) -> Result where E: de::Error, { match NumWorkers::parse(value) { Ok(num_workers) => Ok(num_workers), Err(AtError::InvalidValue { expected, got, .. }) => Err( de::Error::invalid_value(de::Unexpected::Str(&got), &expected), ), Err(_) => unreachable!(), } } } deserializer.deserialize_string(NumWorkersVisitor) } }