about summary refs log tree commit diff
path: root/src/actions/update.rs
blob: a2bc08dce1dca86cefca6642daa52f19f6a6c631 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use std::io::{self, Read};

use crate::{
    files::{Locations, RepositoryPaths},
    history::{FileChange, FileHistory},
    text_diff::TextChange,
};

use super::ActionOptions;

pub fn update(command_options: ActionOptions) -> io::Result<()> {
    let locations = Locations::from(&command_options);

    let entries = locations
        .get_repository_paths()
        .expect("Could not traverse files.");

    for element in entries {
        update_file(element, &locations)?;
    }

    Ok(())
}

fn update_file(paths: RepositoryPaths, locations: &Locations) -> io::Result<()> {
    let new_state = match paths {
        RepositoryPaths::Deleted(deleted) => {
            let mut history_file = deleted.load_history_file()?;
            let file_history = FileHistory::from_file(&mut history_file).unwrap();
            if !file_history.file_is_deleted() {
                let mut new_history = file_history;
                new_history.add_change(FileChange::Deleted);
                Some((history_file, new_history))
            } else {
                None
            }
        }
        RepositoryPaths::Untracked(untracked) => {
            let mut file = untracked.load_file()?;

            let mut file_content = String::new();
            file.read_to_string(&mut file_content)?;

            let change = FileChange::Updated(vec![TextChange::Inserted {
                at: 0,
                new_content: file_content,
            }]);

            let mut new_history = FileHistory::default();
            new_history.add_change(change);

            Some((untracked.create_history_file(locations)?, new_history))
        }
        RepositoryPaths::Tracked(tracked) => {
            let mut history_file = tracked.load_history_file()?;
            let mut tracked_file = tracked.load_tracked_file()?;

            let file_history = FileHistory::from_file(&mut history_file).unwrap();

            let mut new_content = String::new();
            tracked_file.read_to_string(&mut new_content)?;

            let old_content = file_history.get_content();

            let changes = TextChange::diff(&old_content, &new_content);

            let mut new_history = file_history;
            new_history.add_change(FileChange::Updated(changes));
            new_history.set_cursor(new_history.cursor() + 1);

            Some((history_file, new_history))
        }
    };

    if let Some((mut history_file, new_file_history)) = new_state {
        new_file_history.write_to_file(&mut history_file)?;
    }

    Ok(())
}