pub trait Builder<W: Write> {
type Error: Error;
fn build<'re>(
writer: W,
records: impl Iterator<Item = &'re Record>,
) -> Result<(), Self::Error> {
let mut state = Self::create(writer)?;
for record in records {
state.next(record)?;
}
state.finalize()
}
fn build_string<'re>(
records: impl Iterator<Item = &'re Record>,
) -> Result<String, <Self as Builder<&'??? mut Vec<u8>>>::Error> { // what type should I use?
let mut buffer = Vec::new();
Self::<???>::build(&mut buffer, records)?; // same question
Ok(String::from_utf8_lossy(buffer.as_slice()).to_string())
}
fn create(writer: W) -> Result<Self, Self::Error>;
fn next(&mut self, record: &Record) -> Result<(), Self::Error>;
fn finalize(&mut self) -> Result<(), Self::Error>;
}
据我所知,不可能实现我在这里尝试做的事情。如果那是正确的,那么实现默认
build_string
方法的最佳方法是什么,以便我可以在实现 Builder
的类型上访问它?
解决方案:
pub trait Builder<W: Write>: Sized {
type Error: std::error::Error;
fn build<'re>(writer: W, records: impl Iterator<Item = &'re Record>) -> Result<W, Self::Error> {
let mut state = Self::create(writer)?;
for record in records {
state.next(record)?;
}
state.finalize()
}
fn create(writer: W) -> Result<Self, Self::Error>;
fn next(&mut self, record: &Record) -> Result<(), Self::Error>;
fn finalize(self) -> Result<W, Self::Error>;
}
pub trait BuilderString: Builder<Vec<u8>> {
fn build_string<'re>(records: impl Iterator<Item = &'re Record>) -> Result<String, Self::Error>;
}
impl<T> BuilderString for T
where
T: Builder<Vec<u8>>,
{
fn build_string<'re>(records: impl Iterator<Item = &'re Record>) -> Result<String, Self::Error> {
let buffer = Vec::new();
let buffer = Self::build(buffer, records)?;
Ok(String::from_utf8_lossy(buffer.as_slice()).to_string())
}
}
感谢 Seaish on Rust 编程语言 Discord 服务器。