访问由Take或Chain

时间:2015-10-14 00:10:14

标签: rust

我正在编写一个关于Google Brotli解压缩算法的Rust实现,该算法在流的末尾使用固定数量的“隐式零”来启用某些优化。

Google C实现使用各种计数器的意大利面条代码执行此操作,但我想在Rust std :: io库中使用适配器。类似的东西:

pub struct StreamBitReader<R> {
    reader: Chain<R,Take<Repeat>>,
    ...
}

其中'R'是位读取器结构包装的基础Read。但是,在许多情况下,解压缩算法会检查它是否“溢出”了流,它通过检查读取的隐式零字节数来实现。这在安全的Rust中似乎是不可能的,因为除非我遗漏了某些东西,否则无法获得Chain的组件的引用。

构造Chain时,它将获取(移动)基础Read结构的所有权,然后隐藏在私有成员中。

有没有办法构建Take<Repeat>部分,即使在limit()适配器获得所有权后,我也可以访问Take Chain的fn。

1 个答案:

答案 0 :(得分:1)

我知道一种方式,但我认为它不适合你的目标。

use std::io::{self, Read};

fn main() {
    let file = io::empty();
    let zeroes = io::repeat(0);
    let mut ten_zeroes = zeroes.take(10);
    {
        let mut with_zeroes = file.chain(ten_zeroes.by_ref());
        let mut buf = [0; 5];  
        with_zeroes.read(&mut buf);
    }
    println!("{}", ten_zeroes.limit());
}

密钥为Read::by_ref,返回可变引用。 Read是针对实现Read的类型的任何可变引用而实现的,因此您可以将引用的所有权提供给Chain

诀窍是你必须先破坏Chain才能再次使用内部对象。将它存储在结构中也是非常痛苦/不可能的。

您最好的选择可能是编写自己的ZeroPadded适配器,其中包含ChainRepeatTake并提供limit方法。

如果没有其他人提供更好的答案,我还可以看到在适配器上添加方法的功能请求。使用into_inner方法消耗适配器并返回包装的项目并不罕见,但您也可以使用as_inner返回对包装对象的引用。