use tor_rpcbase as rpc;
use super::{ReqMeta, RequestId};
use crate::err::RequestParseError;
#[derive(Debug, serde::Deserialize)]
pub(crate) struct InvalidRequest {
id: Option<Possibly<RequestId>>,
obj: Option<Possibly<rpc::ObjectId>>,
meta: Option<Possibly<ReqMeta>>,
method: Option<Possibly<String>>,
params: Option<serde_json::Value>,
}
#[derive(Debug, serde::Deserialize)]
#[serde(untagged)]
enum Possibly<T> {
Good(T),
#[allow(dead_code)] Bad(serde_json::Value),
}
impl InvalidRequest {
pub(crate) fn id(&self) -> Option<&RequestId> {
match &self.id {
Some(Possibly::Good(id)) => Some(id),
_ => None,
}
}
pub(crate) fn error(&self) -> RequestParseError {
use Possibly::*;
use RequestParseError as E;
match self.id {
None => return E::IdMissing,
Some(Bad(_)) => return E::IdType,
_ => {}
}
match self.obj {
None => return E::ObjMissing,
Some(Bad(_)) => return E::ObjType,
_ => {}
}
match &self.method {
None => return E::MethodMissing,
Some(Bad(_)) => return E::MethodType,
Some(Good(name)) if !rpc::is_method_name(name) => return E::NoSuchMethod,
_ => {}
}
if matches!(self.meta, Some(Bad(_))) {
return E::MetaType;
}
if self.params.is_none() {
return E::MissingParams;
}
E::ParamType
}
}