templater: extract indent function to text_util module

This prepares for adding generic template object for reformatting.
This commit is contained in:
Yuya Nishihara 2023-03-05 12:01:30 +09:00
parent 82604eda02
commit 2af2aca7ff
2 changed files with 34 additions and 13 deletions

View File

@ -17,7 +17,7 @@ use std::io;
use jujutsu_lib::backend::{Signature, Timestamp};
use crate::formatter::{FormatRecorder, Formatter, PlainTextFormatter};
use crate::time_util;
use crate::{text_util, time_util};
pub trait Template<C> {
fn format(&self, context: &C, formatter: &mut dyn Formatter) -> io::Result<()>;
@ -139,18 +139,14 @@ where
fn format(&self, context: &C, formatter: &mut dyn Formatter) -> io::Result<()> {
let mut recorder = FormatRecorder::new();
self.content.format(context, &mut recorder)?;
let mut new_line = true;
recorder.replay_with(formatter, |formatter, data| {
for line in data.split_inclusive(|&c| c == b'\n') {
if new_line && line != b"\n" {
// Prefix inherits the current labels. This is implementation detail
// and may be fixed later.
self.prefix.format(context, formatter)?;
}
formatter.write_all(line)?;
new_line = line.ends_with(b"\n");
}
Ok(())
text_util::write_indented(formatter, &recorder, |formatter| {
// If Template::format() returned a custom error type, we would need to
// handle template evaluation error out of this closure:
// prefix.format(context, &mut prefix_recorder)?;
// write_indented(formatter, recorded, |formatter| {
// prefix_recorder.replay(formatter)
// })
self.prefix.format(context, formatter)
})
}
}

View File

@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::io;
use crate::formatter::{FormatRecorder, Formatter};
pub fn complete_newline(s: impl Into<String>) -> String {
let mut s = s.into();
if !s.is_empty() && !s.ends_with('\n') {
@ -19,3 +23,24 @@ pub fn complete_newline(s: impl Into<String>) -> String {
}
s
}
/// Indents each line by the given prefix preserving labels.
pub fn write_indented(
formatter: &mut dyn Formatter,
recorded_content: &FormatRecorder,
mut write_prefix: impl FnMut(&mut dyn Formatter) -> io::Result<()>,
) -> io::Result<()> {
let mut new_line = true;
recorded_content.replay_with(formatter, |formatter, data| {
for line in data.split_inclusive(|&c| c == b'\n') {
if new_line && line != b"\n" {
// Prefix inherits the current labels. This is implementation detail
// and may be fixed later.
write_prefix(formatter)?;
}
formatter.write_all(line)?;
new_line = line.ends_with(b"\n");
}
Ok(())
})
}