Refactor sidecars
This commit is contained in:
56
crates/pile-value/src/extract/item/group.rs
Normal file
56
crates/pile-value/src/extract/item/group.rs
Normal file
@@ -0,0 +1,56 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use pile_config::Label;
|
||||
|
||||
use crate::{
|
||||
extract::traits::{ExtractState, ObjectExtractor},
|
||||
value::{Item, PileValue},
|
||||
};
|
||||
|
||||
pub struct GroupExtractor {
|
||||
item: Item,
|
||||
}
|
||||
|
||||
impl GroupExtractor {
|
||||
pub fn new(item: &Item) -> Self {
|
||||
Self { item: item.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl ObjectExtractor for GroupExtractor {
|
||||
async fn field(
|
||||
&self,
|
||||
_state: &ExtractState,
|
||||
name: &Label,
|
||||
args: Option<&str>,
|
||||
) -> Result<Option<PileValue>, std::io::Error> {
|
||||
if args.is_some() {
|
||||
return Ok(None);
|
||||
}
|
||||
Ok(self
|
||||
.item
|
||||
.group()
|
||||
.get(name)
|
||||
.map(|item| PileValue::ObjectExtractor(Arc::new(super::ItemExtractor::new(item)))))
|
||||
}
|
||||
|
||||
async fn fields(&self) -> Result<Vec<Label>, std::io::Error> {
|
||||
Ok(self.item.group().keys().cloned().collect())
|
||||
}
|
||||
|
||||
async fn to_json(&self, _state: &ExtractState) -> Result<serde_json::Value, std::io::Error> {
|
||||
Ok(serde_json::Value::Object(
|
||||
self.item
|
||||
.group()
|
||||
.iter()
|
||||
.map(|(k, v)| {
|
||||
(
|
||||
k.to_string(),
|
||||
serde_json::Value::String(format!("<GroupItem ({})>", v.key())),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -25,8 +25,8 @@ mod toml;
|
||||
use pile_config::Label;
|
||||
pub use toml::*;
|
||||
|
||||
mod sidecar;
|
||||
pub use sidecar::*;
|
||||
mod group;
|
||||
pub use group::*;
|
||||
|
||||
use crate::{
|
||||
extract::{
|
||||
@@ -78,8 +78,8 @@ impl ItemExtractor {
|
||||
PileValue::ObjectExtractor(Arc::new(TomlExtractor::new(item))),
|
||||
),
|
||||
(
|
||||
Label::new("sidecar").unwrap(),
|
||||
PileValue::ObjectExtractor(Arc::new(SidecarExtractor::new(item))),
|
||||
Label::new("groups").unwrap(),
|
||||
PileValue::ObjectExtractor(Arc::new(GroupExtractor::new(item))),
|
||||
),
|
||||
]),
|
||||
};
|
||||
@@ -109,7 +109,8 @@ impl ObjectExtractor for ItemExtractor {
|
||||
Label::new("exif").unwrap(),
|
||||
Label::new("pdf").unwrap(),
|
||||
Label::new("json").unwrap(),
|
||||
Label::new("sidecar").unwrap(),
|
||||
Label::new("toml").unwrap(),
|
||||
Label::new("groups").unwrap(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
use pile_config::Label;
|
||||
use std::sync::OnceLock;
|
||||
use tracing::trace;
|
||||
|
||||
use super::TomlExtractor;
|
||||
use crate::{
|
||||
extract::traits::{ExtractState, ObjectExtractor},
|
||||
value::{Item, PileValue},
|
||||
};
|
||||
|
||||
pub struct SidecarExtractor {
|
||||
item: Item,
|
||||
output: OnceLock<Option<TomlExtractor>>,
|
||||
}
|
||||
|
||||
impl SidecarExtractor {
|
||||
pub fn new(item: &Item) -> Self {
|
||||
Self {
|
||||
item: item.clone(),
|
||||
output: OnceLock::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl ObjectExtractor for SidecarExtractor {
|
||||
async fn field(
|
||||
&self,
|
||||
state: &ExtractState,
|
||||
name: &Label,
|
||||
args: Option<&str>,
|
||||
) -> Result<Option<PileValue>, std::io::Error> {
|
||||
trace!(
|
||||
?args,
|
||||
key = self.item.key().as_str(),
|
||||
"Getting field {name:?} from SidecarExtractor",
|
||||
);
|
||||
|
||||
match self
|
||||
.output
|
||||
.get_or_init(|| self.item.sidecar().map(TomlExtractor::new))
|
||||
{
|
||||
Some(x) => Ok(x.field(state, name, args).await?),
|
||||
None => Ok(Some(PileValue::Null)),
|
||||
}
|
||||
}
|
||||
|
||||
async fn fields(&self) -> Result<Vec<Label>, std::io::Error> {
|
||||
match self
|
||||
.output
|
||||
.get_or_init(|| self.item.sidecar().map(TomlExtractor::new))
|
||||
{
|
||||
Some(x) => Ok(x.fields().await?),
|
||||
None => Ok(Vec::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user