Compare commits

..

No commits in common. "main" and "0.2.0" have entirely different histories.
main ... 0.2.0

4 changed files with 25 additions and 42 deletions

View File

@ -25,8 +25,7 @@ check:
cargo deny check cargo deny check
serve: wasm serve: wasm
cd woweb; \ cargo run --package woweb
cargo run
release: $(DIST_DIR) wasm release: $(DIST_DIR) wasm
cargo build --package woweb --release cargo build --package woweb --release

View File

@ -1,6 +1,6 @@
use crdts::list::Op;
use crdts::{CmRDT, List};
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use crdts::{CmRDT, List};
use crdts::list::Op;
#[derive(Clone)] #[derive(Clone)]
pub struct Text { pub struct Text {
@ -9,7 +9,9 @@ pub struct Text {
impl Default for Text { impl Default for Text {
fn default() -> Self { fn default() -> Self {
Self { inner: List::new() } Self {
inner: List::new()
}
} }
} }
@ -23,26 +25,14 @@ impl Display for Text {
impl Text { impl Text {
pub fn apply_ops(&mut self, ops: Vec<Op<u16, String>>) { pub fn apply_ops(&mut self, ops: Vec<Op<u16, String>>) {
ops.iter() ops.iter().for_each(move |op| self.inner.apply(op.to_owned()));
.for_each(move |op| self.inner.apply(op.to_owned()));
} }
pub fn insert_linebreak( pub fn insert_linebreak(&mut self, start: usize, end: usize, src: &str) -> Vec<Op<u16, String>> {
&mut self,
start: usize,
end: usize,
src: &str,
) -> Vec<Op<u16, String>> {
self.insert(start, end, "\n", src) self.insert(start, end, "\n", src)
} }
pub fn insert( pub fn insert(&mut self, start: usize, end: usize, data: &str, src: &str) -> Vec<Op<u16, String>> {
&mut self,
start: usize,
end: usize,
data: &str,
src: &str,
) -> Vec<Op<u16, String>> {
let mut ops: Vec<Op<u16, String>> = Vec::new(); let mut ops: Vec<Op<u16, String>> = Vec::new();
if start < end { if start < end {
@ -65,22 +55,14 @@ impl Text {
} }
pub fn delete_backward(&mut self, start: usize, end: usize, src: &str) -> Vec<Op<u16, String>> { pub fn delete_backward(&mut self, start: usize, end: usize, src: &str) -> Vec<Op<u16, String>> {
if (start == 0 && start == end) || end > self.inner.len() { if (start == 0 && start == end) || end > self.inner.len() { return Vec::new(); }
return Vec::new();
}
let (end, start) = if start == end { let (end, start) = if start == end { (start, start - 1) } else { (end, start) };
(start, start - 1)
} else {
(end, start)
};
self.delete(start, end, src) self.delete(start, end, src)
} }
pub fn delete_forward(&mut self, start: usize, end: usize, src: &str) -> Vec<Op<u16, String>> { pub fn delete_forward(&mut self, start: usize, end: usize, src: &str) -> Vec<Op<u16, String>> {
if start >= self.inner.len() { if start >= self.inner.len() { return Vec::new(); }
return Vec::new();
}
let end = if start == end { start + 1 } else { end }; let end = if start == end { start + 1 } else { end };
self.delete(start, end, src) self.delete(start, end, src)
@ -122,7 +104,7 @@ mod tests {
#[test] #[test]
fn insert_delete() { fn insert_delete() {
let mut t = Text::default(); let mut t = Text::new();
t.insert(0, 0, "Hello", "A"); t.insert(0, 0, "Hello", "A");
t.insert(5, 5, "world!", "A"); t.insert(5, 5, "world!", "A");
t.insert(5, 5, ", ", "B"); t.insert(5, 5, ", ", "B");
@ -139,7 +121,7 @@ mod tests {
#[test] #[test]
fn backspace() { fn backspace() {
let mut t = Text::default(); let mut t = Text::new();
t.insert(0, 0, "Hello", "A"); t.insert(0, 0, "Hello", "A");
t.delete_backward(5, 5, "A"); t.delete_backward(5, 5, "A");
@ -151,7 +133,7 @@ mod tests {
#[test] #[test]
fn delete() { fn delete() {
let mut t = Text::default(); let mut t = Text::new();
t.insert(0, 0, "Hello", "A"); t.insert(0, 0, "Hello", "A");
t.delete_forward(4, 4, "A"); t.delete_forward(4, 4, "A");
@ -163,7 +145,7 @@ mod tests {
#[test] #[test]
fn linebreak() { fn linebreak() {
let mut t = Text::default(); let mut t = Text::new();
t.insert(0, 0, "Hello, world!", "A"); t.insert(0, 0, "Hello, world!", "A");
t.insert_linebreak(6, 6, "A"); t.insert_linebreak(6, 6, "A");
@ -177,10 +159,10 @@ mod tests {
#[test] #[test]
fn apply_ops() { fn apply_ops() {
let mut t_a = Text::default(); let mut t_a = Text::new();
let ops_a = t_a.insert(0, 0, "Hello, world!", "A"); let ops_a = t_a.insert(0, 0, "Hello, world!", "A");
let mut t_b = Text::default(); let mut t_b = Text::new();
t_b.apply_ops(ops_a); t_b.apply_ops(ops_a);
assert_eq!(t_b.to_string(), "Hello, world!"); assert_eq!(t_b.to_string(), "Hello, world!");
@ -191,6 +173,7 @@ mod tests {
let ops_b = t_b.insert(7,7, "cruel ", "B"); let ops_b = t_b.insert(7,7, "cruel ", "B");
t_a.apply_ops(ops_b); t_a.apply_ops(ops_b);
assert_eq!(t_a.to_string(), "Hello, cruel distributed world!"); assert_eq!(t_a.to_string(), "Hello, cruel distributed world!");
assert_eq!(t_b.to_string(), "Hello, cruel distributed world!"); assert_eq!(t_b.to_string(), "Hello, cruel distributed world!");
} }

View File

@ -1,13 +1,13 @@
use axum::routing::get; use axum::routing::get;
use axum::Router; use axum::Router;
use axum_extra::routing::SpaRouter; use axum_extra::routing::SpaRouter;
use dist_text::text::Text;
use std::env; use std::env;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::sync::Arc; use std::sync::Arc;
use tokio::sync::{broadcast, RwLock}; use tokio::sync::{broadcast, RwLock};
use tower_http::trace::TraceLayer; use tower_http::trace::TraceLayer;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
use dist_text::text::Text;
mod ws; mod ws;

View File

@ -9,8 +9,8 @@ use axum::{
response::IntoResponse, response::IntoResponse,
}; };
use dist_text::crdts::list::Op;
use futures::{sink::SinkExt, stream::StreamExt}; use futures::{sink::SinkExt, stream::StreamExt};
use dist_text::crdts::list::Op;
use crate::AppState; use crate::AppState;
@ -84,5 +84,6 @@ async fn handle_socket(stream: WebSocket, state: Arc<AppState>) {
tokio::select! { tokio::select! {
_ = (&mut send_task) => recv_task.abort(), _ = (&mut send_task) => recv_task.abort(),
_ = (&mut recv_task) => send_task.abort(), _ = (&mut recv_task) => send_task.abort(),
}; }
;
} }