Skip to content

Commit

Permalink
feat(trial): implement grapheme clustered input
Browse files Browse the repository at this point in the history
  • Loading branch information
max-niederman committed Jun 11, 2024
1 parent 5a41982 commit df19af6
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/trial/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ impl History {
}

/// Push a typed grapheme cluster to the history.
fn push_typed(&mut self, typed: &str) {
pub fn push_typed(&mut self, typed: &str) {
debug_assert_eq!(typed.graphemes(true).count(), 1);

// Push the index of the cluster.
Expand Down
66 changes: 65 additions & 1 deletion src/trial/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ mod history;

use history::History;

use unicode_segmentation::UnicodeSegmentation;

/// The state of a trial.
pub struct Trial {

Check warning on line 8 in src/trial/mod.rs

View workflow job for this annotation

GitHub Actions / Test

struct `Trial` is never constructed

Check warning on line 8 in src/trial/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

struct `Trial` is never constructed

warning: struct `Trial` is never constructed --> src/trial/mod.rs:8:12 | 8 | pub struct Trial { | ^^^^^
/// The history of typed grapheme clusters and reference grapheme clusters.
Expand Down Expand Up @@ -35,7 +37,9 @@ impl Trial {
pub fn process(&mut self, input: Input) {
match input {
Input::TypeScalar(c) => {
self.working_grapheme_cluster.push(c);
if let Some(finished_cluster) = push_to_working_cluster(&mut self.working_grapheme_cluster, c) {
self.history.push_typed(&finished_cluster);
}
}
Input::DeleteGraphemeCluster if self.working_grapheme_cluster.is_empty() => {
todo!()
Expand All @@ -49,3 +53,63 @@ impl Trial {
}
}
}

/// Push a scalar value to the working grapheme cluster, returning the previous cluster if it was finished.
fn push_to_working_cluster(working_grapheme_cluster: &mut String, scalar: char) -> Option<String> {

Check warning on line 58 in src/trial/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

function `push_to_working_cluster` is never used

warning: function `push_to_working_cluster` is never used --> src/trial/mod.rs:58:4 | 58 | fn push_to_working_cluster(working_grapheme_cluster: &mut String, scalar: char) -> Option<String> { | ^^^^^^^^^^^^^^^^^^^^^^^
working_grapheme_cluster.push(scalar);

let mut clusters = working_grapheme_cluster.graphemes(true);
let first_cluster = clusters.next().unwrap();

if let Some(new_cluster) = clusters.next() {
let first_cluster = first_cluster.to_owned();
let new_cluster = new_cluster.to_owned();

*working_grapheme_cluster = new_cluster;

Some(first_cluster)
} else {
None
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn push_to_working_cluster_handles_latin() {
let mut working_grapheme_cluster = String::new();

assert_eq!(
push_to_working_cluster(&mut working_grapheme_cluster, 'a'),
None
);
assert_eq!(
push_to_working_cluster(&mut working_grapheme_cluster, 'a'),
Some("a".to_owned())
);

assert_eq!(
push_to_working_cluster(&mut working_grapheme_cluster, 'é'),
Some("a".to_owned())
);
assert_eq!(
push_to_working_cluster(&mut working_grapheme_cluster, 'a'),
Some("é".to_owned())
);

assert_eq!(
push_to_working_cluster(&mut working_grapheme_cluster, 'a'),
Some("a".to_owned())
);
assert_eq!(
push_to_working_cluster(&mut working_grapheme_cluster, '\u{0302}'), // combining circumflex accent
None
);
assert_eq!(
push_to_working_cluster(&mut working_grapheme_cluster, 'a'),
Some("a\u{0302}".to_owned())
);
}
}

0 comments on commit df19af6

Please sign in to comment.