pub struct Optional<const KEY: &'static str, T: serde::de::DeserializeOwned = String>(
pub Option<T>,
);
impl<const KEY: &'static str, T: serde::de::DeserializeOwned + std::fmt::Display> std::fmt::Display
for Optional<KEY, T>
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Optional(None) => write!(f, "None"),
Optional(Some(value)) => write!(f, "{}", value),
}
}
}
impl<const KEY: &'static str> PartialEq<&str> for Optional<KEY, String> {
fn eq(&self, other: &&str) -> bool {
match self {
Optional(None) => false,
Optional(Some(value)) => value == *other,
}
}
}
impl<const KEY: &'static str, T: serde::de::DeserializeOwned> Optional<KEY, T> {
pub fn error<S: AsRef<str>>(self, msg: S) -> ft_sdk::SpecialError {
ft_sdk::single_error(KEY, msg)
}
}
impl<const KEY: &'static str, T: serde::de::DeserializeOwned> ft_sdk::FromRequest
for Optional<KEY, T>
{
fn from_request(req: &http::Request<serde_json::Value>) -> Result<Self, ft_sdk::Error> {
match req.body() {
serde_json::Value::Null => {
Err(ft_sdk::single_error(KEY, "body is Null, expected Object").into())
}
serde_json::Value::Object(map) => {
if let Some(value) = map.get(KEY) {
Ok(serde_json::from_value(value.clone())
.map(Some)
.map(Optional)?)
} else {
Ok(Optional(None))
}
}
_ => Err(ft_sdk::single_error(KEY, "body is not json object").into()),
}
}
}