use serde::{Deserialize, Serialize};
use super::OcsStatus;
use super::text::lossy_string;
#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)]
pub struct Meta {
#[serde(default, deserialize_with = "lossy_string")]
status: String,
#[serde(default, deserialize_with = "lossy_string")]
statuscode: String,
#[serde(default, deserialize_with = "lossy_string")]
message: String,
#[serde(default, deserialize_with = "lossy_string")]
totalitems: String,
#[serde(default, deserialize_with = "lossy_string")]
itemsperpage: String,
}
impl Meta {
pub fn status(&self) -> &str {
&self.status
}
pub fn statuscode(&self) -> &str {
&self.statuscode
}
pub fn message(&self) -> &str {
&self.message
}
pub fn totalitems(&self) -> &str {
&self.totalitems
}
pub fn itemsperpage(&self) -> &str {
&self.itemsperpage
}
pub fn code(&self) -> Option<u16> {
self.statuscode.trim().parse().ok()
}
pub fn verdict(&self) -> Option<OcsStatus> {
self.code()
.map(OcsStatus::from_statuscode)
.or_else(|| OcsStatus::from_status_text(&self.status))
}
pub fn is_ok(&self) -> bool {
self.verdict().is_some_and(OcsStatus::is_ok)
}
}
#[cfg(test)]
mod tests {
use super::Meta;
use crate::envelope::OcsStatus;
#[test]
fn accepts_string_fields() {
let meta: Meta = serde_json::from_str(
r#"{"status":"ok","statuscode":200,"message":"","totalitems":"","itemsperpage":""}"#,
)
.unwrap();
assert_eq!(meta.code(), Some(200));
assert!(meta.is_ok());
}
#[test]
fn accepts_numeric_fields() {
let meta: Meta =
serde_json::from_str(r#"{"status":"ok","statuscode":200,"totalitems":3}"#).unwrap();
assert_eq!(meta.statuscode(), "200");
assert_eq!(meta.totalitems(), "3");
assert_eq!(meta.verdict(), Some(OcsStatus::Ok));
}
#[test]
fn missing_fields_default_to_empty() {
let meta: Meta = serde_json::from_str(r#"{"status":"failure"}"#).unwrap();
assert_eq!(meta.statuscode(), "");
assert_eq!(meta.code(), None);
assert_eq!(meta.verdict(), Some(OcsStatus::Failure));
assert!(!meta.is_ok());
}
#[test]
fn unknown_verdict_is_not_success() {
let meta: Meta = serde_json::from_str(r#"{"status":"","statuscode":""}"#).unwrap();
assert_eq!(meta.verdict(), None);
assert!(!meta.is_ok());
}
}