pub mod print;
pub mod use_as;
pub mod field;
pub mod result;
pub mod error;
pub(crate) mod async_fn;
pub use self::{
field::{TransformField, caps::Caps, set::Set, shorten::Shorten, trim::Trim},
print::DebugPrint,
use_as::Use,
};
#[cfg(feature = "action-http")]
pub mod http;
#[cfg(feature = "action-http")]
pub use self::http::Http;
#[cfg(feature = "action-feed")]
pub mod feed;
#[cfg(feature = "action-feed")]
pub use self::feed::Feed;
#[cfg(feature = "action-json")]
pub mod json;
#[cfg(feature = "action-json")]
pub use self::json::Json;
#[cfg(feature = "action-html")]
pub mod html;
#[cfg(feature = "action-html")]
pub use self::html::Html;
use self::{
error::{TransformError, TransformErrorKind},
result::TransformedEntry,
};
use super::{Action, ActionContext, ActionResult};
use crate::{
actres_try,
entry::Entry,
external_save::ExternalSave,
maybe_send::{MaybeSend, MaybeSendSync},
sources::Source,
};
use std::convert::Infallible;
pub trait Transform: MaybeSendSync {
type Err: Into<TransformErrorKind>;
fn transform_entry(
&mut self,
entry: Entry,
) -> impl Future<Output = Result<Vec<TransformedEntry>, Self::Err>> + MaybeSend;
}
#[derive(Clone, Debug)]
pub struct TransformAction<T>(pub T);
impl Transform for () {
type Err = Infallible;
async fn transform_entry(&mut self, _entry: Entry) -> Result<Vec<TransformedEntry>, Self::Err> {
Ok(vec![TransformedEntry::default()])
}
}
impl Transform for Infallible {
type Err = Infallible;
async fn transform_entry(&mut self, _entry: Entry) -> Result<Vec<TransformedEntry>, Self::Err> {
match *self {}
}
}
#[cfg(feature = "nightly")]
impl Transform for ! {
type Err = !;
async fn transform_entry(&mut self, _entry: Entry) -> Result<Vec<TransformedEntry>, Self::Err> {
match *self {}
}
}
impl<T> Transform for Option<T>
where
T: Transform,
{
type Err = T::Err;
async fn transform_entry(&mut self, entry: Entry) -> Result<Vec<TransformedEntry>, Self::Err> {
let Some(inner) = self else {
return Ok(vec![TransformedEntry::default()]);
};
inner.transform_entry(entry).await
}
}
impl<T> Transform for &mut T
where
T: Transform,
{
type Err = T::Err;
fn transform_entry(
&mut self,
entry: Entry,
) -> impl Future<Output = Result<Vec<TransformedEntry>, Self::Err>> + MaybeSend {
(*self).transform_entry(entry)
}
}
impl<T> Action for TransformAction<T>
where
T: Transform,
{
type Err = TransformError;
async fn apply<S, E>(
&mut self,
entries: Vec<Entry>,
_ctx: ActionContext<'_, S, E>,
) -> ActionResult<Self::Err>
where
S: Source,
E: ExternalSave,
{
let mut transformed_entries = Vec::new();
for entry in entries {
let entries =
actres_try!(transform_old_entry_into_new_entries(&mut self.0, entry).await);
transformed_entries.extend(entries);
}
ActionResult::Ok(transformed_entries)
}
}
async fn transform_old_entry_into_new_entries<T>(
this: &mut T,
old_entry: Entry,
) -> Result<Vec<Entry>, TransformError>
where
T: Transform,
{
this.transform_entry(old_entry.clone())
.await
.map(|vec| {
vec.into_iter()
.map(|transformed_entry| transformed_entry.into_entry(&old_entry))
.collect()
})
.map_err(|kind| TransformError {
kind: kind.into(),
original_entry: old_entry,
})
}