use crabstep::{OutputData, PropertyIterator, deserializer::iter::Property};
#[derive(Debug)]
pub struct TypeLengthPair {
pub type_index: i64,
pub length: u64,
}
#[inline(always)]
pub fn as_type_length_pair<'a>(property: &'a mut Property<'a, 'a>) -> Option<TypeLengthPair> {
if let Property::Group(group) = property {
let mut iter = group.iter();
if let Some(Property::Primitive(OutputData::SignedInteger(type_index))) = iter.next()
&& let Some(Property::Primitive(OutputData::UnsignedInteger(length))) = iter.next()
{
return Some(TypeLengthPair {
type_index: *type_index,
length: *length,
});
}
}
None
}
#[must_use]
#[inline(always)]
pub fn as_signed_integer(property: &Property<'_, '_>) -> Option<i64> {
if let Property::Group(group) = property {
let mut iter = group.iter();
let val = iter.next()?;
if let Property::Primitive(OutputData::SignedInteger(value)) = val {
return Some(*value);
} else if let Property::Object { name, data, .. } = val
&& *name == "NSNumber"
{
let mut data_iter = data.clone();
return as_signed_integer(&data_iter.next()?);
}
}
None
}
#[must_use]
#[inline(always)]
pub fn as_unsigned_integer<'a>(property: &'a Property<'a, 'a>) -> Option<u64> {
if let Property::Group(group) = property {
let mut iter = group.iter();
let val = iter.next()?;
if let Property::Primitive(OutputData::UnsignedInteger(value)) = val {
return Some(*value);
} else if let Property::Object { name, data, .. } = val
&& *name == "NSNumber"
{
let mut data_iter = data.clone();
return as_unsigned_integer(&data_iter.next()?);
}
}
None
}
#[must_use]
#[inline(always)]
pub fn as_float<'a>(property: &'a Property<'a, 'a>) -> Option<f64> {
if let Property::Group(group) = property {
let mut iter = group.iter();
let val = iter.next()?;
if let Property::Primitive(OutputData::Double(value)) = val {
return Some(*value);
} else if let Property::Object { name, data, .. } = val
&& *name == "NSNumber"
{
let mut data_iter = data.clone();
return as_float(&data_iter.next()?);
}
}
None
}
#[inline(always)]
pub fn as_nsstring<'a>(property: &'a mut Property<'a, 'a>) -> Option<&'a str> {
if let Property::Group(group) = property {
let mut iter = group.iter_mut();
if let Some(Property::Object { name, data, .. }) = iter.next()
&& (*name == "NSString" || *name == "NSAttributedString" || *name == "NSMutableString")
&& let Some(Property::Group(prim)) = data.next()
&& let Some(Property::Primitive(OutputData::String(s))) = prim.first()
{
return Some(s);
}
}
None
}
#[inline(always)]
pub fn as_ns_dictionary<'a>(
property: &'a mut Property<'a, 'a>,
) -> Option<&'a mut PropertyIterator<'a, 'a>> {
if let Property::Group(group) = property {
let mut iter = group.iter_mut();
if let Some(Property::Object {
class: _,
name,
data,
}) = iter.next()
&& *name == "NSDictionary"
{
return Some(data);
}
}
None
}
#[inline(always)]
pub fn as_nsurl<'a>(property: &'a mut Property<'a, 'a>) -> Option<&'a str> {
if let Property::Group(groups) = property {
for level1 in groups.iter_mut() {
if let Property::Object {
name,
data: url_data,
..
} = level1
{
if *name != "NSURL" {
continue;
}
for level2 in url_data {
if let Property::Group(mut inner) = level2 {
for level3 in &mut inner {
if let Property::Object {
name,
data: str_data,
..
} = level3
{
if *name != "NSString" {
continue;
}
for level4 in str_data {
if let Property::Group(bottom) = level4 {
for p in bottom {
if let Property::Primitive(OutputData::String(s)) = p {
return Some(s);
}
}
}
}
}
}
}
}
}
}
}
None
}