mirror of https://github.com/sigoden/aichat
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
1.5 KiB
Rust
66 lines
1.5 KiB
Rust
use crate::utils::AbortSignal;
|
|
|
|
use anyhow::{Context, Result};
|
|
use tokio::sync::mpsc::UnboundedSender;
|
|
|
|
pub struct ReplyHandler {
|
|
sender: UnboundedSender<ReplyEvent>,
|
|
buffer: String,
|
|
abort: AbortSignal,
|
|
}
|
|
|
|
impl ReplyHandler {
|
|
pub fn new(sender: UnboundedSender<ReplyEvent>, abort: AbortSignal) -> Self {
|
|
Self {
|
|
sender,
|
|
abort,
|
|
buffer: String::new(),
|
|
}
|
|
}
|
|
|
|
pub fn text(&mut self, text: &str) -> Result<()> {
|
|
// debug!("ReplyText: {}", text);
|
|
if text.is_empty() {
|
|
return Ok(());
|
|
}
|
|
self.buffer.push_str(text);
|
|
let ret = self
|
|
.sender
|
|
.send(ReplyEvent::Text(text.to_string()))
|
|
.with_context(|| "Failed to send ReplyEvent:Text");
|
|
self.safe_ret(ret)?;
|
|
Ok(())
|
|
}
|
|
|
|
pub fn done(&mut self) -> Result<()> {
|
|
// debug!("ReplyDone");
|
|
let ret = self
|
|
.sender
|
|
.send(ReplyEvent::Done)
|
|
.with_context(|| "Failed to send ReplyEvent::Done");
|
|
self.safe_ret(ret)?;
|
|
Ok(())
|
|
}
|
|
|
|
pub fn get_buffer(&self) -> &str {
|
|
&self.buffer
|
|
}
|
|
|
|
pub fn get_abort(&self) -> AbortSignal {
|
|
self.abort.clone()
|
|
}
|
|
|
|
fn safe_ret(&self, ret: Result<()>) -> Result<()> {
|
|
if ret.is_err() && self.abort.aborted() {
|
|
return Ok(());
|
|
}
|
|
ret
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum ReplyEvent {
|
|
Text(String),
|
|
Done,
|
|
}
|