use operational_transform::OperationSeq; use tokio::sync::{watch, mpsc, broadcast, Mutex}; use tonic::async_trait; use crate::{Controller, Error}; use crate::buffer::factory::{leading_noop, tailing_noop, OperationFactory}; use super::TextChange; pub struct BufferController { content: watch::Receiver, operations: mpsc::Sender, stream: Mutex>, } impl BufferController { pub(crate) fn new( content: watch::Receiver, operations: mpsc::Sender, stream: Mutex>, ) -> Self { BufferController { content, operations, stream } } } #[async_trait] impl OperationFactory for BufferController { fn content(&self) -> String { self.content.borrow().clone() } } #[async_trait] impl Controller for BufferController { type Input = OperationSeq; async fn recv(&self) -> Result { let op = self.stream.lock().await.recv().await?; let after = self.content.borrow().clone(); let skip = leading_noop(op.ops()) as usize; let before_len = op.base_len(); let tail = tailing_noop(op.ops()) as usize; let span = skip..before_len-tail; let content = after[skip..after.len()-tail].to_string(); Ok(TextChange { span, content }) } async fn send(&self, op: OperationSeq) -> Result<(), Error> { Ok(self.operations.send(op).await?) } }