use serde_json::Value;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum RequestId {
Null,
Int(u64),
String(String),
}
impl RequestId {
pub fn parse(value: Option<&Value>) -> Self {
match value {
None => Self::Null,
Some(Value::Null) => Self::Null,
Some(Value::Number(number)) => number
.as_u64()
.or_else(|| number.as_i64().and_then(|v| u64::try_from(v).ok()))
.map(Self::Int)
.unwrap_or_else(|| Self::String(number.to_string())),
Some(Value::String(value)) => value
.parse::<u64>()
.map(Self::Int)
.unwrap_or_else(|_| Self::String(value.clone())),
Some(other) => Self::String(other.to_string()),
}
}
pub fn name(&self) -> &'static str {
match self {
Self::Null => "null",
Self::Int(_) => "int",
Self::String(_) => "string",
}
}
pub fn as_u64(&self) -> Option<u64> {
match self {
Self::Int(value) => Some(*value),
Self::String(value) => value.parse::<u64>().ok(),
Self::Null => None,
}
}
pub fn as_str(&self) -> Option<&str> {
match self {
Self::String(value) => Some(value),
Self::Null | Self::Int(_) => None,
}
}
pub fn is_null(&self) -> bool {
matches!(self, Self::Null)
}
pub fn value_json(&self) -> Value {
match self {
Self::Null => Value::Null,
Self::Int(value) => Value::from(*value),
Self::String(value) => Value::String(value.clone()),
}
}
}