]> git.lizzy.rs Git - rust.git/blob - crates/ra_ide_db/src/source_change.rs
94e118dd8cab14c7108313947d6bd119d304d8f9
[rust.git] / crates / ra_ide_db / src / source_change.rs
1 //! This modules defines type to represent changes to the source code, that flow
2 //! from the server to the client.
3 //!
4 //! It can be viewed as a dual for `AnalysisChange`.
5
6 use ra_db::{FileId, FilePosition, RelativePathBuf, SourceRootId};
7 use ra_text_edit::TextEdit;
8
9 #[derive(Debug, Clone)]
10 pub struct SourceChange {
11     /// For display in the undo log in the editor
12     pub label: String,
13     pub source_file_edits: Vec<SourceFileEdit>,
14     pub file_system_edits: Vec<FileSystemEdit>,
15     pub cursor_position: Option<FilePosition>,
16     pub is_snippet: bool,
17 }
18
19 impl SourceChange {
20     /// Creates a new SourceChange with the given label
21     /// from the edits.
22     pub fn from_edits<L: Into<String>>(
23         label: L,
24         source_file_edits: Vec<SourceFileEdit>,
25         file_system_edits: Vec<FileSystemEdit>,
26     ) -> Self {
27         SourceChange {
28             label: label.into(),
29             source_file_edits,
30             file_system_edits,
31             cursor_position: None,
32             is_snippet: false,
33         }
34     }
35
36     /// Creates a new SourceChange with the given label,
37     /// containing only the given `SourceFileEdits`.
38     pub fn source_file_edits<L: Into<String>>(label: L, edits: Vec<SourceFileEdit>) -> Self {
39         let label = label.into();
40         assert!(label.starts_with(char::is_uppercase));
41         SourceChange {
42             label: label,
43             source_file_edits: edits,
44             file_system_edits: vec![],
45             cursor_position: None,
46             is_snippet: false,
47         }
48     }
49
50     /// Creates a new SourceChange with the given label,
51     /// containing only the given `FileSystemEdits`.
52     pub(crate) fn file_system_edits<L: Into<String>>(label: L, edits: Vec<FileSystemEdit>) -> Self {
53         SourceChange {
54             label: label.into(),
55             source_file_edits: vec![],
56             file_system_edits: edits,
57             cursor_position: None,
58             is_snippet: false,
59         }
60     }
61
62     /// Creates a new SourceChange with the given label,
63     /// containing only a single `SourceFileEdit`.
64     pub fn source_file_edit<L: Into<String>>(label: L, edit: SourceFileEdit) -> Self {
65         SourceChange::source_file_edits(label, vec![edit])
66     }
67
68     /// Creates a new SourceChange with the given label
69     /// from the given `FileId` and `TextEdit`
70     pub fn source_file_edit_from<L: Into<String>>(
71         label: L,
72         file_id: FileId,
73         edit: TextEdit,
74     ) -> Self {
75         SourceChange::source_file_edit(label, SourceFileEdit { file_id, edit })
76     }
77
78     /// Creates a new SourceChange with the given label
79     /// from the given `FileId` and `TextEdit`
80     pub fn file_system_edit<L: Into<String>>(label: L, edit: FileSystemEdit) -> Self {
81         SourceChange::file_system_edits(label, vec![edit])
82     }
83
84     /// Sets the cursor position to the given `FilePosition`
85     pub fn with_cursor(mut self, cursor_position: FilePosition) -> Self {
86         self.cursor_position = Some(cursor_position);
87         self
88     }
89
90     /// Sets the cursor position to the given `FilePosition`
91     pub fn with_cursor_opt(mut self, cursor_position: Option<FilePosition>) -> Self {
92         self.cursor_position = cursor_position;
93         self
94     }
95 }
96
97 #[derive(Debug, Clone)]
98 pub struct SourceFileEdit {
99     pub file_id: FileId,
100     pub edit: TextEdit,
101 }
102
103 #[derive(Debug, Clone)]
104 pub enum FileSystemEdit {
105     CreateFile { source_root: SourceRootId, path: RelativePathBuf },
106     MoveFile { src: FileId, dst_source_root: SourceRootId, dst_path: RelativePathBuf },
107 }
108
109 pub struct SingleFileChange {
110     pub label: String,
111     pub edit: TextEdit,
112 }
113
114 impl SingleFileChange {
115     pub fn into_source_change(self, file_id: FileId) -> SourceChange {
116         SourceChange {
117             label: self.label,
118             source_file_edits: vec![SourceFileEdit { file_id, edit: self.edit }],
119             file_system_edits: Vec::new(),
120             cursor_position: None,
121             is_snippet: false,
122         }
123     }
124 }