|
@@ -1,41 +1,41 @@
|
|
|
use serde::{de, de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
|
|
|
use std::{fmt, fmt::Formatter};
|
|
|
|
|
|
+/// [OTString] uses [String] as its inner container.
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
|
-pub struct FlowyStr(pub String);
|
|
|
+pub struct OTString(pub String);
|
|
|
|
|
|
-impl FlowyStr {
|
|
|
+impl OTString {
|
|
|
+ /// Returns the number of UTF-16 code units in this string.
|
|
|
///
|
|
|
- /// # Arguments
|
|
|
- ///
|
|
|
- /// * `delta`: The delta you want to iterate over.
|
|
|
- /// * `interval`: The range for the cursor movement.
|
|
|
+ /// The length of strings behaves differently in different languages. For example: [Dart] string's
|
|
|
+ /// length is calculated with UTF-16 code units. The method [utf16_len] returns the length of a
|
|
|
+ /// String in UTF-16 code units.
|
|
|
///
|
|
|
/// # Examples
|
|
|
///
|
|
|
/// ```
|
|
|
- /// use lib_ot::core::FlowyStr;
|
|
|
- /// let utf16_len = FlowyStr::from("👋").utf16_len();
|
|
|
+ /// use lib_ot::core::OTString;
|
|
|
+ /// let utf16_len = OTString::from("👋").utf16_len();
|
|
|
/// assert_eq!(utf16_len, 2);
|
|
|
/// let bytes_len = String::from("👋").len();
|
|
|
/// assert_eq!(bytes_len, 4);
|
|
|
///
|
|
|
/// ```
|
|
|
- /// https://stackoverflow.com/questions/2241348/what-is-unicode-utf-8-utf-16
|
|
|
pub fn utf16_len(&self) -> usize {
|
|
|
count_utf16_code_units(&self.0)
|
|
|
}
|
|
|
|
|
|
- pub fn utf16_code_unit_iter(&self) -> Utf16CodeUnitIterator {
|
|
|
+ pub fn utf16_iter(&self) -> Utf16CodeUnitIterator {
|
|
|
Utf16CodeUnitIterator::new(self)
|
|
|
}
|
|
|
|
|
|
- /// Return a new string with the given [Interval]
|
|
|
+ /// Returns a new string with the given [Interval]
|
|
|
/// # Examples
|
|
|
///
|
|
|
/// ```
|
|
|
- /// use lib_ot::core::{FlowyStr, Interval};
|
|
|
- /// let s: FlowyStr = "你好\n😁".into();
|
|
|
+ /// use lib_ot::core::{OTString, Interval};
|
|
|
+ /// let s: OTString = "你好\n😁".into();
|
|
|
/// assert_eq!(s.utf16_len(), 5);
|
|
|
/// let output1 = s.sub_str(Interval::new(0, 2)).unwrap();
|
|
|
/// assert_eq!(output1, "你好");
|
|
@@ -69,21 +69,21 @@ impl FlowyStr {
|
|
|
/// # Examples
|
|
|
///
|
|
|
/// ```
|
|
|
- /// use lib_ot::core::FlowyStr;
|
|
|
- /// let s: FlowyStr = "👋😁👋".into(); ///
|
|
|
+ /// use lib_ot::core::OTString;
|
|
|
+ /// let s: OTString = "👋😁👋".into(); ///
|
|
|
/// let mut iter = s.utf16_code_point_iter();
|
|
|
/// assert_eq!(iter.next().unwrap(), "👋".to_string());
|
|
|
/// assert_eq!(iter.next().unwrap(), "😁".to_string());
|
|
|
/// assert_eq!(iter.next().unwrap(), "👋".to_string());
|
|
|
/// assert_eq!(iter.next(), None);
|
|
|
///
|
|
|
- /// let s: FlowyStr = "👋12ab一二👋".into(); ///
|
|
|
+ /// let s: OTString = "👋12ab一二👋".into(); ///
|
|
|
/// let mut iter = s.utf16_code_point_iter();
|
|
|
/// assert_eq!(iter.next().unwrap(), "👋".to_string());
|
|
|
/// assert_eq!(iter.next().unwrap(), "1".to_string());
|
|
|
/// assert_eq!(iter.next().unwrap(), "2".to_string());
|
|
|
///
|
|
|
- /// assert_eq!(iter.skip(FlowyStr::from("ab一二").utf16_len()).next().unwrap(), "👋".to_string());
|
|
|
+ /// assert_eq!(iter.skip(OTString::from("ab一二").utf16_len()).next().unwrap(), "👋".to_string());
|
|
|
/// ```
|
|
|
#[allow(dead_code)]
|
|
|
pub fn utf16_code_point_iter(&self) -> FlowyUtf16CodePointIterator {
|
|
@@ -91,7 +91,7 @@ impl FlowyStr {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl std::ops::Deref for FlowyStr {
|
|
|
+impl std::ops::Deref for OTString {
|
|
|
type Target = String;
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
@@ -99,46 +99,46 @@ impl std::ops::Deref for FlowyStr {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl std::ops::DerefMut for FlowyStr {
|
|
|
+impl std::ops::DerefMut for OTString {
|
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
|
&mut self.0
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl std::convert::From<String> for FlowyStr {
|
|
|
+impl std::convert::From<String> for OTString {
|
|
|
fn from(s: String) -> Self {
|
|
|
- FlowyStr(s)
|
|
|
+ OTString(s)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl std::convert::From<&str> for FlowyStr {
|
|
|
+impl std::convert::From<&str> for OTString {
|
|
|
fn from(s: &str) -> Self {
|
|
|
s.to_owned().into()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl std::fmt::Display for FlowyStr {
|
|
|
+impl std::fmt::Display for OTString {
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
|
f.write_str(&self.0)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl std::ops::Add<&str> for FlowyStr {
|
|
|
- type Output = FlowyStr;
|
|
|
+impl std::ops::Add<&str> for OTString {
|
|
|
+ type Output = OTString;
|
|
|
|
|
|
- fn add(self, rhs: &str) -> FlowyStr {
|
|
|
+ fn add(self, rhs: &str) -> OTString {
|
|
|
let new_value = self.0 + rhs;
|
|
|
new_value.into()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl std::ops::AddAssign<&str> for FlowyStr {
|
|
|
+impl std::ops::AddAssign<&str> for OTString {
|
|
|
fn add_assign(&mut self, rhs: &str) {
|
|
|
self.0 += rhs;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl Serialize for FlowyStr {
|
|
|
+impl Serialize for OTString {
|
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
|
where
|
|
|
S: Serializer,
|
|
@@ -147,15 +147,15 @@ impl Serialize for FlowyStr {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<'de> Deserialize<'de> for FlowyStr {
|
|
|
- fn deserialize<D>(deserializer: D) -> Result<FlowyStr, D::Error>
|
|
|
+impl<'de> Deserialize<'de> for OTString {
|
|
|
+ fn deserialize<D>(deserializer: D) -> Result<OTString, D::Error>
|
|
|
where
|
|
|
D: Deserializer<'de>,
|
|
|
{
|
|
|
- struct FlowyStrVisitor;
|
|
|
+ struct OTStringVisitor;
|
|
|
|
|
|
- impl<'de> Visitor<'de> for FlowyStrVisitor {
|
|
|
- type Value = FlowyStr;
|
|
|
+ impl<'de> Visitor<'de> for OTStringVisitor {
|
|
|
+ type Value = OTString;
|
|
|
|
|
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
|
formatter.write_str("a str")
|
|
@@ -168,19 +168,19 @@ impl<'de> Deserialize<'de> for FlowyStr {
|
|
|
Ok(s.into())
|
|
|
}
|
|
|
}
|
|
|
- deserializer.deserialize_str(FlowyStrVisitor)
|
|
|
+ deserializer.deserialize_str(OTStringVisitor)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
pub struct Utf16CodeUnitIterator<'a> {
|
|
|
- s: &'a FlowyStr,
|
|
|
+ s: &'a OTString,
|
|
|
byte_offset: usize,
|
|
|
utf16_offset: usize,
|
|
|
utf16_count: usize,
|
|
|
}
|
|
|
|
|
|
impl<'a> Utf16CodeUnitIterator<'a> {
|
|
|
- pub fn new(s: &'a FlowyStr) -> Self {
|
|
|
+ pub fn new(s: &'a OTString) -> Self {
|
|
|
Utf16CodeUnitIterator {
|
|
|
s,
|
|
|
byte_offset: 0,
|
|
@@ -219,12 +219,12 @@ impl<'a> Iterator for Utf16CodeUnitIterator<'a> {
|
|
|
}
|
|
|
|
|
|
pub struct FlowyUtf16CodePointIterator<'a> {
|
|
|
- s: &'a FlowyStr,
|
|
|
+ s: &'a OTString,
|
|
|
offset: usize,
|
|
|
}
|
|
|
|
|
|
impl<'a> FlowyUtf16CodePointIterator<'a> {
|
|
|
- pub fn new(s: &'a FlowyStr, offset: usize) -> Self {
|
|
|
+ pub fn new(s: &'a OTString, offset: usize) -> Self {
|
|
|
FlowyUtf16CodePointIterator { s, offset }
|
|
|
}
|
|
|
}
|
|
@@ -278,15 +278,15 @@ pub fn len_utf8_from_first_byte(b: u8) -> usize {
|
|
|
|
|
|
#[cfg(test)]
|
|
|
mod tests {
|
|
|
- use crate::core::flowy_str::FlowyStr;
|
|
|
+ use crate::core::flowy_str::OTString;
|
|
|
use crate::core::interval::Interval;
|
|
|
|
|
|
#[test]
|
|
|
fn flowy_str_code_unit() {
|
|
|
- let size = FlowyStr::from("👋").utf16_len();
|
|
|
+ let size = OTString::from("👋").utf16_len();
|
|
|
assert_eq!(size, 2);
|
|
|
|
|
|
- let s: FlowyStr = "👋 \n👋".into();
|
|
|
+ let s: OTString = "👋 \n👋".into();
|
|
|
let output = s.sub_str(Interval::new(0, size)).unwrap();
|
|
|
assert_eq!(output, "👋");
|
|
|
|
|
@@ -302,7 +302,7 @@ mod tests {
|
|
|
|
|
|
#[test]
|
|
|
fn flowy_str_sub_str_in_chinese2() {
|
|
|
- let s: FlowyStr = "😁 \n".into();
|
|
|
+ let s: OTString = "😁 \n".into();
|
|
|
let size = s.utf16_len();
|
|
|
assert_eq!(size, 4);
|
|
|
|
|
@@ -314,7 +314,7 @@ mod tests {
|
|
|
|
|
|
#[test]
|
|
|
fn flowy_str_sub_str_in_english() {
|
|
|
- let s: FlowyStr = "ab".into();
|
|
|
+ let s: OTString = "ab".into();
|
|
|
let size = s.utf16_len();
|
|
|
assert_eq!(size, 2);
|
|
|
|
|
@@ -324,7 +324,7 @@ mod tests {
|
|
|
|
|
|
#[test]
|
|
|
fn flowy_str_utf16_code_point_iter_test2() {
|
|
|
- let s: FlowyStr = "👋😁👋".into();
|
|
|
+ let s: OTString = "👋😁👋".into();
|
|
|
let iter = s.utf16_code_point_iter();
|
|
|
let result = iter.skip(1).take(1).collect::<String>();
|
|
|
assert_eq!(result, "😁".to_string());
|