use super::error::LcelError;
use super::runnable_trait::Runnable;
use super::sequence::RunnableSequence;
pub trait RunnableExt<Input: Send + Sync + 'static, Output: Send + Sync + 'static>:
Runnable<Input, Output>
where
Self::Error: Into<LcelError>,
Self: Sized + 'static,
{
fn pipe<O2, R2>(self, other: R2) -> RunnableSequence<Input, O2>
where
O2: Send + Sync + 'static,
R2: Runnable<Output, O2> + Send + Sync + 'static,
R2::Error: Into<LcelError>,
{
RunnableSequence::from_pair(self, other)
}
fn into_sequence(self) -> RunnableSequence<Input, Output> {
RunnableSequence::from_single(self)
}
}
impl<I, O, R> RunnableExt<I, O> for R
where
I: Send + Sync + 'static,
O: Send + Sync + 'static,
R: Runnable<I, O>,
R::Error: Into<LcelError>,
R: Sized + 'static,
{
}
#[cfg(test)]
mod tests {
use super::*;
use crate::RunnableConfig;
use async_trait::async_trait;
use futures_util::StreamExt;
struct Double;
#[async_trait]
impl Runnable<i32, i32> for Double {
type Error = std::convert::Infallible;
async fn invoke(&self, input: i32, _config: Option<RunnableConfig>) -> Result<i32, Self::Error> {
Ok(input * 2)
}
}
struct AddSuffix;
#[async_trait]
impl Runnable<i32, String> for AddSuffix {
type Error = std::convert::Infallible;
async fn invoke(&self, input: i32, _config: Option<RunnableConfig>) -> Result<String, Self::Error> {
Ok(format!("result: {}", input))
}
}
#[tokio::test]
async fn pipe_creates_sequence() {
let chain = Double.pipe(AddSuffix);
let result = chain.invoke(5, None).await.unwrap();
assert_eq!(result, "result: 10");
}
#[tokio::test]
async fn pipe_chain_multiple() {
let chain = Double.pipe(Double).pipe(AddSuffix);
let result = chain.invoke(3, None).await.unwrap();
assert_eq!(result, "result: 12"); }
#[tokio::test]
async fn pipe_stream_works() {
let chain = Double.pipe(AddSuffix);
let mut stream = chain.stream(5, None).await.unwrap();
let result = stream.next().await.unwrap().unwrap();
assert_eq!(result, "result: 10");
}
}