I am writing a line wrapping program with the textwrap
library and want to store unwrapped and wrapped lines under different structs. Code:
struct Lines<'a> {
opt: textwrap::Options<'a>,
buf: String,
}
impl<'a> Lines<'a> {
fn new(options: &Options) -> Self {
let opt = textwrap::Options::new(options.line_width)
.wrap_algorithm(WrapAlgorithm::OptimalFit(Penalties::new()));
Self {
opt,
buf: String::new(),
}
}
fn push(&mut self, v: &[u8]) -> Result<(), str::Utf8Error> {
self.buf.push_str(str::from_utf8(v)?);
Ok(())
}
fn push_char(&mut self, c: char) {
self.buf.push(c);
}
}
struct WrappedLines<'a> {
buf: String,
wrapped: Vec<Cow<'a, str>>,
}
impl<'a> Into<WrappedLines<'a>> for Lines<'a> {
fn into(self) -> WrappedLines<'a> {
WrappedLines {
buf: self.buf,
wrapped: textwrap::wrap(&self.buf, self.opt),
}
}
}
I know that reference to self.buf
will last long enough because it is owned by
the same struct, but the compiler gives this message:
error[E0515]: cannot return value referencing local data `self.buf`
--> src/main.rs:64:9
|
64 | / WrappedLines {
65 | | buf: self.buf,
66 | | wrapped: textwrap::wrap(&self.buf, self.opt),
| | --------- `self.buf` is borrowed here
67 | | }
| |_________^ returns a value referencing data owned by the current function
error[E0382]: borrow of moved value: `self.buf`
--> src/main.rs:66:37
|
65 | buf: self.buf,
| -------- value moved here
66 | wrapped: textwrap::wrap(&self.buf, self.opt),
| ^^^^^^^^^ value borrowed here after move
|
= note: move occurs because `self.buf` has type `String`, which does not implement the `Copy` trait
How do I fix this?
I tried moving the wrapping code to another member function:
impl<'a> WrappedLines<'a> {
fn wrap(&'a mut self) {
let opt =
textwrap::Options::new(79).wrap_algorithm(WrapAlgorithm::OptimalFit(Penalties::new()));
self.wrapped = textwrap::wrap(&self.buf, opt);
}
}
This removes the error but I would like to keep the wrapping code inside the into
function.