从brotly-sys迁移至Dropbox Brotli实现Coder trait遇类型错误
Brotli库实现Coder接口的类型不匹配错误修复
问题背景
原使用已停止维护的Brotly-sys库,转用Dropbox的Brotli库后,为压缩/解压实现Coder接口时出现编译类型不匹配错误,涉及DecompressorWriter和CompressorWriter的finish方法实现。
原实现代码
use std::io::{self, Write}; pub use brotli::writer::DecompressorWriter; pub use brotli::enc::writer::CompressorWriter; use super::Coder; impl<W: Write> Coder<W> for DecompressorWriter<W> { fn get_mut(&mut self) -> &mut W { DecompressorWriter::get_mut(self) } fn finish(self) -> std::io::Result<W> { DecompressorWriter::flush(&mut self).map_err(|_| { io::Error::new(io::ErrorKind::Other, "brotli decoder failed to finalize stream") }); } fn finish_boxed(self: Box<Self>) -> io::Result<W> { self.finish() } } impl<W: Write> Coder<W> for CompressorWriter<W> { fn get_mut(&mut self) -> &mut W { CompressorWriter::get_mut(self) } fn finish(self) -> std::io::Result<W> { self.flush()?; CompressorWriter::flush(&mut self).map_err(|_| { io::Error::new(io::ErrorKind::Other, "brotli encoder failed to finalize stream") }) } fn finish_boxed(self: Box<Self>) -> io::Result<W> { self.finish() } }
编译错误
error[E0308]: mismatched types --> lib/src/codecs/brotli.rs:13:24 | 13 | fn finish(self) -> std::io::Result<W> { | ------ ^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found `()` | | | implicitly returns `()` as its body has no tail or `return` expression | = note: expected enum `std::result::Result<W, std::io::Error>` found unit type `()` error[E0308]: mismatched types --> lib/src/codecs/brotli.rs:31:9 | 24 | impl<W: Write> Coder<W> for CompressorWriter<W> { | - this type parameter ... 29 | fn finish(self) -> std::io::Result<W> { | ------------------ expected `std::result::Result<W, std::io::Error>` because of return type 30 | self.flush()?; 31 | / CompressorWriter::flush(&mut self).map_err(|_| { 32 | | io::Error::new(io::ErrorKind::Other, "brotli encoder failed to finalize stream") 33 | | }) | |__________^ expected type parameter `W`, found `()` | = note: expected enum `std::result::Result<W, _>` found enum `std::result::Result<(), _>`
补充:flush仅返回Result<()>,无法提供底层W实例;Coder接口要求finish返回std::io::Result<W>。
修复方案
错误根源
- DecompressorWriter的finish:代码末尾多了分号,导致返回
()而非Result;且未提取底层的W实例。 - CompressorWriter的finish:仅调用
flush得到Result<()>,未获取底层W,不符合返回类型要求。
修改后的代码
use std::io::{self, Write}; pub use brotli::writer::DecompressorWriter; pub use brotli::enc::writer::CompressorWriter; use super::Coder; impl<W: Write> Coder<W> for DecompressorWriter<W> { fn get_mut(&mut self) -> &mut W { DecompressorWriter::get_mut(self) } fn finish(mut self) -> std::io::Result<W> { // 完成flush并处理错误 DecompressorWriter::flush(&mut self).map_err(|_| { io::Error::new(io::ErrorKind::Other, "brotli decoder failed to finalize stream") })?; // 提取底层writer并返回 Ok(self.into_inner()) } fn finish_boxed(self: Box<Self>) -> io::Result<W> { self.finish() } } impl<W: Write> Coder<W> for CompressorWriter<W> { fn get_mut(&mut self) -> &mut W { CompressorWriter::get_mut(self) } fn finish(mut self) -> std::io::Result<W> { // 执行flush操作 self.flush()?; CompressorWriter::flush(&mut self).map_err(|_| { io::Error::new(io::ErrorKind::Other, "brotli encoder failed to finalize stream") })?; // 提取底层writer并返回 Ok(self.into_inner()) } fn finish_boxed(self: Box<Self>) -> io::Result<W> { self.finish() } }
关键修改点
- 移除
DecompressorWriter::flush后的分号,改用?传播错误,确保错误正确向上传递。 - 使用
into_inner方法从Brotli的writer中提取底层W实例,包装为Ok(W)返回,符合Coder接口的返回类型要求。 - 对
CompressorWriter先完成所有flush操作,确保压缩流完全写入底层writer后,再提取并返回W。
内容的提问来源于stack exchange,提问作者Vana
相关产品推荐
相关产品推荐

