use crate::deserializer::iter::Property;
use crate::models::output_data::OutputData;
impl<'a, 'b: 'a> Property<'a, 'b> {
#[must_use]
pub fn as_date(&self) -> Option<f64> {
let mut data = self.object_in_classes(&["NSDate"])?;
match data.next()? {
Property::Group(group) => match group.first()? {
Property::Primitive(OutputData::Double(seconds)) => Some(*seconds),
_ => None,
},
_ => None,
}
}
#[must_use]
pub fn as_unix_time(&self) -> Option<f64> {
self.as_date().map(|seconds| seconds + 978_307_200.0)
}
}
#[cfg(test)]
mod tests {
use alloc::{vec, vec::Vec};
use crate::deserializer::foundation::test_support::load;
use crate::deserializer::typedstream::TypedStreamDeserializer;
#[test]
fn root_object_resolves_as_date() {
let bytes = load("foundation/NSDate");
let mut ts = TypedStreamDeserializer::new(&bytes);
assert_eq!(ts.root().unwrap().as_date(), Some(21692800.0));
}
#[test]
fn as_date_and_unix_time() {
let bytes = load("foundation/NestedScalars");
let mut ts = TypedStreamDeserializer::new(&bytes);
let root = ts.oxidize().unwrap();
let dates: Vec<f64> = ts
.resolve_properties(root)
.unwrap()
.filter_map(|group| group.as_date())
.collect();
assert_eq!(dates, vec![21692800.0]);
let mut ts = TypedStreamDeserializer::new(&bytes);
let root = ts.oxidize().unwrap();
let unix: Vec<f64> = ts
.resolve_properties(root)
.unwrap()
.filter_map(|group| group.as_unix_time())
.collect();
assert_eq!(unix, vec![1_000_000_000.0]);
}
#[test]
fn scalar_accessors_reject_wrong_types() {
let bytes = load("foundation/NumberInt");
let mut ts = TypedStreamDeserializer::new(&bytes);
let root = ts.oxidize().unwrap();
let group = ts.resolve_properties(root).unwrap().next().unwrap();
assert!(!group.is_null());
assert_eq!(group.as_date(), None);
assert_eq!(group.as_unix_time(), None);
assert_eq!(group.as_url(), None);
}
}