Skip to content

Commit

Permalink
Simplify code to list files and mutants (#438)
Browse files Browse the repository at this point in the history
  • Loading branch information
sourcefrog authored Nov 12, 2024
2 parents a992111 + 6614641 commit d9463d8
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 42 deletions.
66 changes: 27 additions & 39 deletions src/list.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,27 @@
// Copyright 2023-2024 Martin Pool

//! List mutants and files as text.
//! List mutants and files as text or json.

use std::fmt;
use std::io;
#![warn(clippy::pedantic)]
#![allow(clippy::module_name_repetitions)]

use itertools::Itertools;
use serde_json::{json, Value};

use crate::mutate::Mutant;
use crate::path::Utf8PathSlashes;
use crate::source::SourceFile;
use crate::{Options, Result};
use crate::Options;

/// Convert `fmt::Write` to `io::Write`.
pub(crate) struct FmtToIoWrite<W: io::Write>(W);

impl<W: io::Write> FmtToIoWrite<W> {
pub(crate) fn new(w: W) -> Self {
Self(w)
}
}

impl<W: io::Write> fmt::Write for FmtToIoWrite<W> {
fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
self.0.write_all(s.as_bytes()).map_err(|_| fmt::Error)
}
}

pub(crate) fn list_mutants<W: fmt::Write>(
mut out: W,
mutants: &[Mutant],
options: &Options,
) -> Result<()> {
/// Return a string representation of a list of mutants.
///
/// The format is controlled by the `emit_json`, `emit_diffs`, `show_line_col`, and `colors` options.
pub fn list_mutants(mutants: &[Mutant], options: &Options) -> String {
if options.emit_json {
// Panic: only if we created illegal json, which would be a bug.
let mut list: Vec<serde_json::Value> = Vec::new();
for mutant in mutants {
let mut obj = serde_json::to_value(mutant)?;
let mut obj = serde_json::to_value(mutant).expect("Serialize mutant");
if options.emit_diffs {
obj.as_object_mut().unwrap().insert(
"diff".to_owned(),
Expand All @@ -44,26 +30,28 @@ pub(crate) fn list_mutants<W: fmt::Write>(
}
list.push(obj);
}
out.write_str(&serde_json::to_string_pretty(&list)?)?;
serde_json::to_string_pretty(&list).expect("Serialize mutants")
} else {
// TODO: Do we need to check this? Could the console library strip them if they're not
// supported?
let colors = options.colors.active_stdout();
// let mut out = String::with_capacity(200 * mutants.len());
// TODO: Use with_capacity when we can have mutants skip it (#315
let mut out = String::new();
for mutant in mutants {
writeln!(out, "{}", mutant.name(options.show_line_col, colors))?;
out.push_str(&mutant.name(options.show_line_col, colors));
out.push('\n');
if options.emit_diffs {
writeln!(out, "{}", mutant.diff(&mutant.mutated_code()))?;
out.push_str(&mutant.diff(&mutant.mutated_code()));
out.push('\n');
}
}
out
}
Ok(())
}

pub(crate) fn list_files<W: fmt::Write>(
mut out: W,
source_files: &[SourceFile],
options: &Options,
) -> Result<()> {
/// List the source files as json or text.
pub fn list_files(source_files: &[SourceFile], options: &Options) -> String {
if options.emit_json {
let json_list = Value::Array(
source_files
Expand All @@ -76,11 +64,11 @@ pub(crate) fn list_files<W: fmt::Write>(
})
.collect(),
);
writeln!(out, "{}", serde_json::to_string_pretty(&json_list)?)?;
serde_json::to_string_pretty(&json_list).expect("Serialize source files")
} else {
for file in source_files {
writeln!(out, "{}", file.tree_relative_path.to_slash_path())?;
}
source_files
.iter()
.map(|file| file.tree_relative_path.to_slash_path() + "\n")
.join("")
}
Ok(())
}
6 changes: 3 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ use crate::console::Console;
use crate::in_diff::diff_filter;
use crate::interrupt::check_interrupted;
use crate::lab::test_mutants;
use crate::list::{list_files, list_mutants, FmtToIoWrite};
use crate::list::{list_files, list_mutants};
use crate::mutate::{Genre, Mutant};
use crate::options::{Colors, Options, TestTool};
use crate::outcome::{Phase, ScenarioOutcome};
Expand Down Expand Up @@ -461,7 +461,7 @@ fn main() -> Result<()> {

console.clear();
if args.list_files {
list_files(FmtToIoWrite::new(io::stdout()), &discovered.files, &options)?;
print!("{}", list_files(&discovered.files, &options));
return Ok(());
}
let mut mutants = discovered.mutants;
Expand All @@ -475,7 +475,7 @@ fn main() -> Result<()> {
mutants = shard.select(mutants);
}
if args.list {
list_mutants(FmtToIoWrite::new(io::stdout()), &mutants, &options)?;
print!("{}", list_mutants(&mutants, &options));
} else {
let output_dir = OutputDir::new(&output_parent_dir)?;
if let Some(previously_caught) = previously_caught {
Expand Down

0 comments on commit d9463d8

Please sign in to comment.