3 个版本

0.1.0 2019年4月10日
0.1.0-rc12019年4月9日

#219解析工具

MIT 协议

46KB
600

Char-circle

字符串循环缓冲区和就地字符串转换特性。

本包提供了两个关键类型:结构体 CharCircle 和特质 StringTransform。结构体 CharCircle 是一个针对 UTF-8 字符串优化的循环缓冲区,而特质 StringTransform 则基于它提供面向字符的就地字符串转换 API。简而言之,StringTransform 允许您将转换作为迭代器适配器实现,并考虑到了写时复制的优化。

文档

https://docs.rs/char-circle

用法

Char-circle 是一个纯 Rust 库。要使用它,只需将其添加到您的 Cargo.toml

[dependencies]
char-circle = "0.1.0"

lib.rs:

字符串循环缓冲区和就地字符串转换特性。

本包提供了两个关键类型:结构体 CharCircle 和特质 StringTransform。结构体 CharCircle 是一个针对 UTF-8 字符串优化的循环缓冲区,而特质 StringTransform 则基于它提供面向字符的就地字符串转换 API。简而言之,StringTransform 允许您将转换作为迭代器适配器实现,并考虑到了写时复制的优化。

结构体 CharCircle 使用内部可变性。这使得其内容可以被外部迭代器 Chars 消费。因此,结构体 CharCircle 不是 Sync。它通过 RawCircle 实现,后者具有几乎相同的 API,使用外部可变性,线程安全,并且不提供消耗迭代器。

StringTransform特质由迭代器适配器的工厂实现。对于简单的情况,SimpleTransform特质提供了一个由适配器直接实现的替代方案。

示例:转换为大写

无需配置即可实现的转换最易使用SimpleTransform

在此我们实现一个大写转换

use char_circle::{SimpleTransform, Chars};

// Step 1: Define the transform as an iterator adaptor.
struct ToUpper<I>(I);

impl<I> Iterator for ToUpper<I> where I: Iterator<Item=char> {
    type Item = char;
    fn next(&mut self) -> Option<char> {
        self.0.next().map(|ch| ch.to_ascii_uppercase())
    }
}

// Step 2: Define a constructor for the adaptor with `SimpleTransform`.
impl<'a> SimpleTransform<'a> for ToUpper<Chars<'a>> {
    fn transform_chars(chars: Chars<'a>) -> Self {
        ToUpper(chars)
    }
}

// Step 3: Profit!
let s = "can you hear me in the back?";
let s = ToUpper::transform(s);
assert_eq!(&s, "CAN YOU HEAR ME IN THE BACK?");

示例:凯撒密码

需要配置的转换应定义一个工厂,该工厂实现StringTransform

在此我们实现一个使用其密钥配置的凯撒密码

use char_circle::{StringTransform, Chars};

// Step 1: Define the transform as an iterator adaptor.
struct CaesarCipherIter<I> {
    inner: I,
    key: i32,
}

impl<I> Iterator for CaesarCipherIter<I> where I: Iterator<Item=char> {
    type Item = char;
    fn next(&mut self) -> Option<char> {
        let plaintext = self.inner.next()?;
        let ciphertext = plaintext as i32 + self.key;
        let ciphertext = std::char::from_u32(ciphertext as u32).unwrap();
        Some(ciphertext)
    }
}

// Step 2: Define a factory for the adaptor with `StringTransform`.
struct CaesarCipher(i32);

impl<'a> StringTransform<'a> for CaesarCipher {
    type Iter = CaesarCipherIter<Chars<'a>>;
    fn transform_chars(&self, chars: Chars<'a>) -> Self::Iter {
        CaesarCipherIter { inner: chars, key: self.0 }
    }
}

// Step 3: Profit!
let encoder = CaesarCipher(8);
let decoder = CaesarCipher(-8);
let plaintext = "Veni, vidi, vici";
let ciphertext = encoder.transform(plaintext);
assert_eq!(&ciphertext, "^mvq4(~qlq4(~qkq");
let plaintext = decoder.transform(ciphertext);
assert_eq!(&plaintext, "Veni, vidi, vici");

无运行时依赖