Unify WASM and Rust API types

This commit is contained in:
Andras Schmelczer 2025-06-29 17:42:37 +01:00
parent b18a692d46
commit 5378ffb547
16 changed files with 252 additions and 301 deletions

View file

@ -0,0 +1,36 @@
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;
// CursorPosition represents the position of an identifiable cursor in a text
// document based on its (UTF-8) character index.
#[cfg_attr(feature = "wasm", wasm_bindgen)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq, Default)]
pub struct CursorPosition {
pub id: usize,
pub char_index: usize,
}
#[cfg_attr(feature = "wasm", wasm_bindgen)]
impl CursorPosition {
#[cfg_attr(feature = "wasm", wasm_bindgen(constructor))]
#[must_use]
pub fn new(id: usize, char_index: usize) -> Self { Self { id, char_index } }
#[must_use]
pub fn with_index(&self, index: usize) -> Self {
CursorPosition {
id: self.id,
char_index: index,
}
}
#[must_use]
pub fn id(&self) -> usize { self.id }
#[cfg_attr(feature = "wasm", wasm_bindgen(js_name = characterPosition))]
#[must_use]
pub fn char_index(&self) -> usize { self.char_index }
}

View file

@ -0,0 +1,47 @@
#[cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;
use crate::types::cursor_position::CursorPosition;
#[cfg_attr(feature = "wasm", wasm_bindgen)]
#[derive(Debug, Clone, PartialEq, Default)]
pub struct TextWithCursors {
text: String, // wasm-pack doesn't support generics so we can't use Cow here
cursors: Vec<CursorPosition>,
}
#[cfg_attr(feature = "wasm", wasm_bindgen)]
impl TextWithCursors {
#[cfg_attr(feature = "wasm", wasm_bindgen(constructor))]
#[must_use]
pub fn new(text: String, cursors: Vec<CursorPosition>) -> Self {
let length = text.chars().count();
for cursor in &cursors {
debug_assert!(
cursor.char_index <= length,
// cursor.char_index == length means that the cursor is at the end
"Cursor positions must be contained within the text or just after the end"
);
}
Self { text, cursors }
}
#[must_use]
pub fn text(&self) -> String { self.text.to_string() }
#[must_use]
pub fn cursors(&self) -> Vec<CursorPosition> { self.cursors.clone() }
#[must_use]
pub fn new_owned(text: String, cursors: Vec<CursorPosition>) -> Self { Self { text, cursors } }
}
impl<'a> From<&'a str> for TextWithCursors {
fn from(text: &'a str) -> Self {
Self {
text: text.into(),
cursors: Vec::new(),
}
}
}

View file

@ -5,7 +5,7 @@ use wasm_bindgen::prelude::*;
use crate::types::history::History;
/// Wrapper type to expose `(History, String)` to JS.
/// Wrapper type for `(History, String)`
#[cfg_attr(feature = "wasm", wasm_bindgen)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq)]
@ -16,6 +16,7 @@ pub struct TextWithHistory {
#[cfg_attr(feature = "wasm", wasm_bindgen)]
impl TextWithHistory {
#[must_use]
pub fn new(history: History, text: String) -> Self { TextWithHistory { history, text } }
#[must_use]