use std::path::{Path, PathBuf};
use super::{delta::Delta, status::Status};
use crate::file_mode::FileMode;
#[derive(Debug, Clone, PartialEq)]
pub struct FileStatus {
pub(crate) deltas: Vec<Delta>,
pub(crate) destination_is_binary: bool,
pub(crate) destination_mode: FileMode,
pub(crate) destination_path: PathBuf,
pub(crate) largest_new_line_number: u32,
pub(crate) largest_old_line_number: u32,
pub(crate) source_is_binary: bool,
pub(crate) source_mode: FileMode,
pub(crate) source_path: PathBuf,
pub(crate) status: Status,
}
impl FileStatus {
#[inline]
#[must_use]
pub(crate) fn new<F: AsRef<Path>>(
source_path: F,
source_mode: FileMode,
source_is_binary: bool,
destination_path: F,
destination_mode: FileMode,
destination_is_binary: bool,
status: Status,
) -> Self {
Self {
deltas: vec![],
destination_is_binary,
destination_mode,
destination_path: PathBuf::from(destination_path.as_ref()),
largest_new_line_number: 0,
largest_old_line_number: 0,
source_is_binary,
source_mode,
source_path: PathBuf::from(source_path.as_ref()),
status,
}
}
#[inline]
pub fn add_delta(&mut self, delta: Delta) {
let last_old_line_number = delta.old_lines_start() + delta.old_number_lines();
if self.largest_old_line_number < last_old_line_number {
self.largest_old_line_number = last_old_line_number;
}
let last_new_line_number = delta.new_lines_start() + delta.new_number_lines();
if self.largest_new_line_number < last_new_line_number {
self.largest_new_line_number = last_new_line_number;
}
self.deltas.push(delta);
}
#[inline]
#[must_use]
pub const fn status(&self) -> Status {
self.status
}
#[inline]
#[must_use]
pub fn destination_path(&self) -> &Path {
self.destination_path.as_path()
}
#[inline]
#[must_use]
pub const fn destination_mode(&self) -> FileMode {
self.destination_mode
}
#[inline]
#[must_use]
pub const fn destination_is_binary(&self) -> bool {
self.destination_is_binary
}
#[inline]
#[must_use]
pub fn source_path(&self) -> &Path {
self.source_path.as_path()
}
#[inline]
#[must_use]
pub const fn source_mode(&self) -> FileMode {
self.source_mode
}
#[inline]
#[must_use]
pub const fn source_is_binary(&self) -> bool {
self.source_is_binary
}
#[inline]
#[must_use]
pub const fn deltas(&self) -> &Vec<Delta> {
&self.deltas
}
#[inline]
#[must_use]
pub const fn last_old_line_number(&self) -> u32 {
self.largest_old_line_number
}
#[inline]
#[must_use]
pub const fn last_new_line_number(&self) -> u32 {
self.largest_new_line_number
}
}
#[cfg(test)]
mod tests {
use super::*;
fn create_file_stat() -> FileStatus {
FileStatus::new(
Path::new("/from/path"),
FileMode::Normal,
false,
Path::new("/to/path"),
FileMode::Executable,
false,
Status::Modified,
)
}
#[test]
fn status() {
assert_eq!(create_file_stat().status(), Status::Modified);
}
#[test]
fn destination_path() {
assert_eq!(create_file_stat().destination_path(), PathBuf::from("/to/path"));
}
#[test]
fn destination_mode() {
assert_eq!(create_file_stat().destination_mode(), FileMode::Executable);
}
#[test]
fn destination_is_binary() {
assert_eq!(create_file_stat().destination_is_binary(), false);
}
#[test]
fn source_path() {
assert_eq!(create_file_stat().source_path(), PathBuf::from("/from/path"));
}
#[test]
fn source_mode() {
assert_eq!(create_file_stat().source_mode(), FileMode::Normal);
}
#[test]
fn source_is_binary() {
assert_eq!(create_file_stat().source_is_binary(), false);
}
#[test]
fn deltas_empty() {
let file_stat = create_file_stat();
assert_eq!(file_stat.deltas(), &vec![]);
assert_eq!(file_stat.last_old_line_number(), 0);
assert_eq!(file_stat.last_new_line_number(), 0);
}
#[test]
fn deltas_single() {
let mut file_stat = create_file_stat();
let delta = Delta::new("@ path/to/file.rs:56 @ impl Delta {", 10, 12, 3, 4);
file_stat.add_delta(delta.clone());
assert_eq!(file_stat.deltas(), &vec![delta]);
assert_eq!(file_stat.last_old_line_number(), 13);
assert_eq!(file_stat.last_new_line_number(), 16);
}
#[test]
fn deltas_multiple() {
let mut file_stat = create_file_stat();
let delta1 = Delta::new("@ path/to/file.rs:56 @ impl Delta {", 10, 12, 3, 4);
let delta2 = Delta::new("@ path/to/file.rs:156 @ impl Delta {", 110, 2, 10, 3);
file_stat.add_delta(delta1.clone());
file_stat.add_delta(delta2.clone());
assert_eq!(file_stat.deltas(), &vec![delta1, delta2]);
assert_eq!(file_stat.last_old_line_number(), 120);
assert_eq!(file_stat.last_new_line_number(), 16);
}
#[test]
fn deltas_with_second_delta_with_larger_old_line_number() {
let mut file_stat = create_file_stat();
file_stat.add_delta(Delta::new("@ path/to/file.rs:56 @ impl Delta {", 10, 20, 5, 5));
file_stat.add_delta(Delta::new("@ path/to/file.rs:56 @ impl Delta {", 20, 20, 5, 5));
assert_eq!(file_stat.last_old_line_number(), 25);
}
#[test]
fn deltas_with_first_delta_with_larger_old_line_number() {
let mut file_stat = create_file_stat();
file_stat.add_delta(Delta::new("@ path/to/file.rs:56 @ impl Delta {", 20, 20, 5, 5));
file_stat.add_delta(Delta::new("@ path/to/file.rs:56 @ impl Delta {", 10, 20, 5, 5));
assert_eq!(file_stat.last_old_line_number(), 25);
}
#[test]
fn deltas_with_second_delta_with_larger_new_line_number() {
let mut file_stat = create_file_stat();
file_stat.add_delta(Delta::new("@ path/to/file.rs:56 @ impl Delta {", 10, 10, 5, 5));
file_stat.add_delta(Delta::new("@ path/to/file.rs:56 @ impl Delta {", 10, 20, 5, 5));
assert_eq!(file_stat.last_new_line_number(), 25);
}
#[test]
fn deltas_with_first_delta_with_larger_new_line_number() {
let mut file_stat = create_file_stat();
file_stat.add_delta(Delta::new("@ path/to/file.rs:56 @ impl Delta {", 10, 20, 5, 5));
file_stat.add_delta(Delta::new("@ path/to/file.rs:56 @ impl Delta {", 10, 10, 5, 5));
assert_eq!(file_stat.last_new_line_number(), 25);
}
}