strop_engine/editor/git_memory/
file_list.rs1use std::ops::Deref;
3use std::path::Path;
4use std::sync::Arc;
5
6use super::sidebar::Sidebar;
7use ropey::Rope;
8use serde::{Deserialize, Deserializer, Serialize, Serializer};
9use strop_git::memory::ChangedFile;
10
11#[derive(Debug, Clone)]
12pub struct PreparedFiles(Arc<FileList>);
13#[derive(Debug)]
14struct FileList {
15 sha: String,
16 files: Vec<ChangedFile>,
17 by_path: Vec<usize>,
18 text: Rope,
19 sidebar: Sidebar,
20}
21impl PreparedFiles {
22 pub fn new(sha: String, files: Vec<ChangedFile>) -> Self {
23 let mut text = format!("commit {}\n\n", sha.get(..10).unwrap_or(&sha));
24 for file in &files {
25 text.push_str(&strop_core::layout::printable_text(
26 file.path.to_string_lossy(),
27 ));
28 text.push('\n');
29 }
30 let mut by_path: Vec<usize> = (0..files.len()).collect();
31 by_path.sort_unstable_by(|&left, &right| files[left].path.cmp(&files[right].path));
32 let sidebar = Sidebar::build(&files);
33 Self(Arc::new(FileList {
34 sha,
35 files,
36 by_path,
37 text: Rope::from_str(&text),
38 sidebar,
39 }))
40 }
41 pub(crate) fn text(&self) -> Rope {
42 self.0.text.clone()
43 }
44 pub fn sidebar(&self) -> &Sidebar {
45 &self.0.sidebar
46 }
47 pub(crate) fn index_of(&self, path: &Path) -> Option<usize> {
48 let index = self
49 .0
50 .by_path
51 .binary_search_by(|&index| self.0.files[index].path.as_path().cmp(path))
52 .ok()?;
53 Some(self.0.by_path[index])
54 }
55}
56impl Deref for PreparedFiles {
57 type Target = [ChangedFile];
58 fn deref(&self) -> &Self::Target {
59 &self.0.files
60 }
61}
62impl<'a> IntoIterator for &'a PreparedFiles {
63 type Item = &'a ChangedFile;
64 type IntoIter = std::slice::Iter<'a, ChangedFile>;
65 fn into_iter(self) -> Self::IntoIter {
66 self.iter()
67 }
68}
69impl Serialize for PreparedFiles {
70 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
71 (&self.0.sha, &self.0.files).serialize(serializer)
72 }
73}
74impl<'de> Deserialize<'de> for PreparedFiles {
75 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
76 let (sha, files) = Deserialize::deserialize(deserializer)?;
77 Ok(Self::new(sha, files))
78 }
79}