#![allow(dead_code)]
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use async_trait::async_trait;
use futures::StreamExt;
use parking_lot::Mutex;
use chat_engine_sdk::{
ChatEngineBackendPlugin, MessagePluginCtx, PluginError, PluginStream, StreamingEvent,
stream_from_events,
};
pub mod db;
pub enum FakePluginScript {
Events(Vec<StreamingEvent>),
PreError(PluginError),
Hang,
EventsThenHang(Vec<StreamingEvent>),
}
pub struct FakePlugin {
id: String,
script: Mutex<Option<FakePluginScript>>,
calls: AtomicUsize,
}
impl FakePlugin {
#[must_use]
pub fn new(id: &str, script: FakePluginScript) -> Arc<Self> {
Arc::new(Self {
id: id.to_owned(),
script: Mutex::new(Some(script)),
calls: AtomicUsize::new(0),
})
}
#[must_use]
pub fn call_count(&self) -> usize {
self.calls.load(Ordering::SeqCst)
}
}
#[async_trait]
impl ChatEngineBackendPlugin for FakePlugin {
async fn on_message(&self, _ctx: MessagePluginCtx) -> Result<PluginStream, PluginError> {
self.calls.fetch_add(1, Ordering::SeqCst);
let script = self
.script
.lock()
.take()
.unwrap_or(FakePluginScript::Events(vec![]));
match script {
FakePluginScript::Events(events) => Ok(stream_from_events(events)),
FakePluginScript::PreError(e) => Err(e),
FakePluginScript::Hang => Ok(forever_pending_stream()),
FakePluginScript::EventsThenHang(events) => {
let items: Vec<Result<StreamingEvent, PluginError>> =
events.into_iter().map(Ok).collect();
let head = futures::stream::iter(items);
let tail = futures::stream::poll_fn(
|_cx| -> std::task::Poll<Option<Result<StreamingEvent, PluginError>>> {
std::task::Poll::Pending
},
);
Ok(head.chain(tail).boxed())
}
}
}
async fn on_message_recreate(
&self,
ctx: MessagePluginCtx,
) -> Result<PluginStream, PluginError> {
self.on_message(ctx).await
}
fn plugin_instance_id(&self) -> &str {
&self.id
}
}
fn forever_pending_stream() -> PluginStream {
futures::stream::poll_fn(|_cx| std::task::Poll::Pending).boxed()
}