codemp/src/buffer/controller.rs

42 lines
1.1 KiB
Rust
Raw Normal View History

use operational_transform::OperationSeq;
use tokio::sync::{watch, mpsc, broadcast, Mutex};
use tonic::async_trait;
use crate::{Controller, CodempError};
use crate::buffer::factory::{leading_noop, tailing_noop, OperationFactory};
use super::TextChange;
pub struct BufferController {
content: watch::Receiver<String>,
operations: mpsc::Sender<OperationSeq>,
stream: Mutex<broadcast::Receiver<OperationSeq>>,
}
#[async_trait]
impl OperationFactory for BufferController {
fn content(&self) -> String {
self.content.borrow().clone()
}
}
#[async_trait]
impl Controller<TextChange> for BufferController {
type Input = OperationSeq;
async fn recv(&self) -> Result<TextChange, CodempError> {
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<(), CodempError> {
Ok(self.operations.send(op).await?)
}
}