Filter by mime

This commit is contained in:
2026-03-15 10:20:15 -07:00
parent 8041fc7531
commit 979fbb9b0d
30 changed files with 258 additions and 93 deletions

View File

@@ -9,7 +9,7 @@ use crate::{
item::ItemExtractor,
misc::{ArrayExtractor, MapExtractor, VecExtractor},
string::StringExtractor,
traits::{ListExtractor, ObjectExtractor},
traits::{ExtractState, ListExtractor, ObjectExtractor},
},
value::Item,
};
@@ -91,7 +91,11 @@ impl PileValue {
}
}
pub async fn query(&self, query: &ObjectPath) -> Result<Option<Self>, std::io::Error> {
pub async fn query(
&self,
state: &ExtractState,
query: &ObjectPath,
) -> Result<Option<Self>, std::io::Error> {
let mut out: Option<PileValue> = Some(self.clone());
for s in &query.segments {
@@ -106,7 +110,7 @@ impl PileValue {
}
};
out = e.field(name, args.as_deref()).await?;
out = e.field(state, name, args.as_deref()).await?;
}
PathSegment::Index(idx) => {
@@ -121,7 +125,7 @@ impl PileValue {
let idx = if *idx >= 0 {
usize::try_from(*idx).ok()
} else {
usize::try_from(e.len().await? as i64 - idx).ok()
usize::try_from(e.len(state).await? as i64 - idx).ok()
};
let idx = match idx {
@@ -132,7 +136,7 @@ impl PileValue {
}
};
out = e.get(idx).await?;
out = e.get(state, idx).await?;
}
}
}
@@ -147,7 +151,10 @@ impl PileValue {
/// - `ObjectExtractor` is recursed into; returns `Some(Object(map))` with
/// only the fields that had data, or `None` if all fields were absent.
/// - `Array` / `ListExtractor` are treated as opaque leaf values (not descended into).
pub async fn count_fields(&self) -> Result<Option<Value>, std::io::Error> {
pub async fn count_fields(
&self,
state: &ExtractState,
) -> Result<Option<Value>, std::io::Error> {
Ok(match self {
Self::Null => None,
@@ -156,18 +163,18 @@ impl PileValue {
}
Self::Array(x) => (!x.is_empty()).then(|| Value::Number(1u64.into())),
Self::ListExtractor(x) => (!x.is_empty().await?).then(|| Value::Number(1u64.into())),
Self::ListExtractor(x) => (x.len(state).await? > 0).then(|| Value::Number(1u64.into())),
Self::ObjectExtractor(_) | Self::Item(_) => {
let e = self.object_extractor();
let keys = e.fields().await?;
let mut map = Map::new();
for k in &keys {
let v = match e.field(k, None).await? {
let v = match e.field(state, k, None).await? {
Some(x) => x,
None => continue,
};
if let Some(counted) = Box::pin(v.count_fields()).await? {
if let Some(counted) = Box::pin(v.count_fields(state)).await? {
map.insert(k.to_string(), counted);
}
}
@@ -187,7 +194,7 @@ impl PileValue {
}
}
pub async fn to_json(&self) -> Result<Value, std::io::Error> {
pub async fn to_json(&self, state: &ExtractState) -> Result<Value, std::io::Error> {
Ok(match self {
Self::Null => Value::Null,
Self::U64(x) => Value::Number((*x).into()),
@@ -201,12 +208,12 @@ impl PileValue {
Self::Array(_) | Self::ListExtractor(_) => {
let e = self.list_extractor();
return e.to_json().await;
return e.to_json(state).await;
}
Self::ObjectExtractor(_) | Self::Item(_) => {
let e = self.object_extractor();
return e.to_json().await;
return e.to_json(state).await;
}
})
}