Struct afrim_memory::Cursor
source · pub struct Cursor { /* private fields */ }Expand description
The Cursor permits to keep a track of the different positions while moving in the text buffer.
'\0' - 'k' - '\0' - 'w' - '\0' '\0' '\0' - '\'' - 'n' - 'i' - '7' |--> 0
| /| / |
| / | / |
'e' / 'e' / |--> 1
| / | / |
'2' '2' |--> 2
|
| depth
v
§Example
use afrim_memory::{Cursor, Node};
use std::rc::Rc;
let text_buffer = Node::default();
text_buffer.insert(vec!['e', '2'], "é".to_owned());
text_buffer.insert(vec!['i', '7'], "ǐ".to_owned());
// We build our cursor.
let memory = Rc::new(text_buffer);
let mut cursor = Cursor::new(memory, 16);
let input = "nkwe2e2'ni7";
input.chars().for_each(|c| { cursor.hit(c); });
assert_eq!(
cursor.to_sequence(),
vec![
'k', '\0', 'w', '\0', 'e', '2', '\0', 'e', '2', '\0',
'\'', '\0', 'n', '\0', 'i', '7'
]
);Note the partitioning of this input. The cursor can browse through the memory based on an input and save a track of his positions. It’s useful when we want handle backspace operations in an input method engine.
Implementations§
source§impl Cursor
impl Cursor
sourcepub fn new(root: Rc<Node>, capacity: usize) -> Self
pub fn new(root: Rc<Node>, capacity: usize) -> Self
Initializes the cursor of a text buffer.
capacity is the number of hit that the cursor can track. The cursor follows the FIFO
rule. If the capacity is exceeded, the oldest hit will be discarded.
Note: Be careful when you set this capacity. We recommend to select a capacity equal or greater than the maximun sequence length that you want handle.
§Example
use afrim_memory::{Cursor, Node};
use std::rc::Rc;
let text_buffer = Node::default();
let memory = Rc::new(text_buffer);
// A cursor of our text buffer.
let cursor = Cursor::new(memory, 16);Note: It’s recommended to initialize the text buffer with
Node::default to evict unexpected behaviors.
sourcepub fn hit(&mut self, character: char) -> Option<String>
pub fn hit(&mut self, character: char) -> Option<String>
Enters a character in the sequence and returns his corresponding out.
Permits to simulate the user typing in the input method engine. For each character entered, the cursor will move through the text buffer in looking of the corresponding sequence. If the sequence is got (end on a value), his value will be returned.
§Example
use afrim_memory::{Cursor, Node};
use std::rc::Rc;
let text_buffer = Node::default();
text_buffer.insert(vec!['o', 'e'], "œ".to_owned());
let memory = Rc::new(text_buffer);
let mut cursor = Cursor::new(memory, 16);
// let input= "coeur";
assert_eq!(cursor.hit('c'), None);
assert_eq!(cursor.hit('o'), None);
assert_eq!(cursor.hit('e'), Some("œ".to_owned()));
assert_eq!(cursor.hit('u'), None);
assert_eq!(cursor.hit('r'), None);
assert_eq!(cursor.to_sequence(), vec!['\0', 'c', '\0', 'o', 'e', '\0', 'u', '\0', 'r']);Note:
- The
\0at the index 0, marks the beginning of a new sequence and the end of a old. It also represents the root node. - A character don’t necessary need to be in the text buffer. The cursor will create a tempory node to represent it in his internal memory. All characters not present in the text buffer will be at the same depth that the root node.
sourcepub fn undo(&mut self) -> Option<String>
pub fn undo(&mut self) -> Option<String>
Removes the last node and returns his corresponding out. Or simplily, undo the previous hit.
Useful to simulate a backspace operation.
§Example
use afrim_memory::{Cursor, Node};
use std::rc::Rc;
let text_buffer = Node::default();
text_buffer.insert(vec!['o', 'e'], "œ".to_owned());
let memory = Rc::new(text_buffer);
let mut cursor = Cursor::new(memory, 16);
// let input = "coeur";
assert_eq!(cursor.hit('c'), None);
assert_eq!(cursor.hit('o'), None);
assert_eq!(cursor.hit('e'), Some("œ".to_owned()));
assert_eq!(cursor.hit('u'), None);
assert_eq!(cursor.hit('r'), None);
// Undo
assert_eq!(cursor.undo(), None);
assert_eq!(cursor.undo(), None);
assert_eq!(cursor.undo(), Some("œ".to_owned()));
assert_eq!(cursor.undo(), None);
assert_eq!(cursor.undo(), None);
assert_eq!(cursor.to_sequence(), vec!['\0']);Note: Look at the \0 at the end. It represents the root node, and the start of a
new sequence. Even if you remove it until obtain an empty buffer, the cursor will add it
before each new sequence. You can considere it as a delimiter between two sequences. But if
you want clear or verify if the buffer is empty, you can use Cursor::clear or Cursor::is_empty.
sourcepub fn state(&self) -> (Option<String>, usize, char)
pub fn state(&self) -> (Option<String>, usize, char)
Returns the current state of the cursor.
Permits to know the current position in the memory and also the last hit.
§Example
use afrim_memory::{Cursor, Node};
use std::rc::Rc;
let text_buffer = Node::default();
text_buffer.insert(vec!['o', '/'], "ø".to_owned());
let memory = Rc::new(text_buffer);
let mut cursor = Cursor::new(memory, 8);
// The cursor starts always at the root node.
assert_eq!(cursor.state(), (None, 0, '\0'));
cursor.hit('o');
assert_eq!(cursor.state(), (None, 1, 'o'));sourcepub fn to_sequence(&self) -> Vec<char>
pub fn to_sequence(&self) -> Vec<char>
Returns the current sequence in the cursor.
It’s always useful to know what is inside the memory of the cursor for debugging / logging. The
§Example
use afrim_memory::{Cursor, Node};
use std::rc::Rc;
let text_buffer = Node::default();
text_buffer.insert(vec!['.', '.', 'z'], "z̈".to_owned());
let memory = Rc::new(text_buffer);
let mut cursor = Cursor::new(memory, 8);
"z..z".chars().for_each(|c| { cursor.hit(c); });
assert_eq!(cursor.to_sequence(), vec!['\0', 'z', '\0', '.', '.', 'z']);sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Clear the memory of the cursor.
In clearing the internal buffer, all the tracking information will be lost.
§Example
use afrim_memory::{Cursor, Node};
use std::rc::Rc;
let text_buffer = Node::default();
let memory = Rc::new(text_buffer);
let mut cursor = Cursor::new(memory, 8);
"hello".chars().for_each(|c| { cursor.hit(c); });
assert!(!cursor.is_empty());
cursor.clear();
assert!(cursor.is_empty());sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Verify if the cursor is empty.
§Example
use afrim_memory::{Cursor, Node};
use std::rc::Rc;
let text_buffer = Node::default();
let memory = Rc::new(text_buffer);
let mut cursor = Cursor::new(memory, 8);
assert!(cursor.is_empty());
cursor.hit('a');
assert!(!cursor.is_empty());