aboutsummaryrefslogtreecommitdiff
path: root/crates/server/src/conv.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/server/src/conv.rs')
-rw-r--r--crates/server/src/conv.rs82
1 files changed, 71 insertions, 11 deletions
diff --git a/crates/server/src/conv.rs b/crates/server/src/conv.rs
index c7bea15df..0ed989b32 100644
--- a/crates/server/src/conv.rs
+++ b/crates/server/src/conv.rs
@@ -1,23 +1,23 @@
1use languageserver_types::{Range, SymbolKind, Position}; 1use languageserver_types::{Range, SymbolKind, Position, TextEdit};
2use libeditor::{LineIndex, LineCol}; 2use libeditor::{LineIndex, LineCol, Edit, AtomEdit};
3use libsyntax2::{SyntaxKind, TextUnit, TextRange}; 3use libsyntax2::{SyntaxKind, TextUnit, TextRange};
4 4
5pub trait Conv { 5pub trait Conv {
6 type Output; 6 type Output;
7 fn conv(&self) -> Self::Output; 7 fn conv(self) -> Self::Output;
8} 8}
9 9
10pub trait ConvWith { 10pub trait ConvWith {
11 type Ctx; 11 type Ctx;
12 type Output; 12 type Output;
13 fn conv_with(&self, ctx: &Self::Ctx) -> Self::Output; 13 fn conv_with(self, ctx: &Self::Ctx) -> Self::Output;
14} 14}
15 15
16impl Conv for SyntaxKind { 16impl Conv for SyntaxKind {
17 type Output = SymbolKind; 17 type Output = SymbolKind;
18 18
19 fn conv(&self) -> <Self as Conv>::Output { 19 fn conv(self) -> <Self as Conv>::Output {
20 match *self { 20 match self {
21 SyntaxKind::FUNCTION => SymbolKind::Function, 21 SyntaxKind::FUNCTION => SymbolKind::Function,
22 SyntaxKind::STRUCT => SymbolKind::Struct, 22 SyntaxKind::STRUCT => SymbolKind::Struct,
23 SyntaxKind::ENUM => SymbolKind::Enum, 23 SyntaxKind::ENUM => SymbolKind::Enum,
@@ -35,7 +35,7 @@ impl ConvWith for Position {
35 type Ctx = LineIndex; 35 type Ctx = LineIndex;
36 type Output = TextUnit; 36 type Output = TextUnit;
37 37
38 fn conv_with(&self, line_index: &LineIndex) -> TextUnit { 38 fn conv_with(self, line_index: &LineIndex) -> TextUnit {
39 // TODO: UTF-16 39 // TODO: UTF-16
40 let line_col = LineCol { 40 let line_col = LineCol {
41 line: self.line as u32, 41 line: self.line as u32,
@@ -49,8 +49,8 @@ impl ConvWith for TextUnit {
49 type Ctx = LineIndex; 49 type Ctx = LineIndex;
50 type Output = Position; 50 type Output = Position;
51 51
52 fn conv_with(&self, line_index: &LineIndex) -> Position { 52 fn conv_with(self, line_index: &LineIndex) -> Position {
53 let line_col = line_index.line_col(*self); 53 let line_col = line_index.line_col(self);
54 // TODO: UTF-16 54 // TODO: UTF-16
55 Position::new(line_col.line as u64, u32::from(line_col.col) as u64) 55 Position::new(line_col.line as u64, u32::from(line_col.col) as u64)
56 } 56 }
@@ -60,7 +60,7 @@ impl ConvWith for TextRange {
60 type Ctx = LineIndex; 60 type Ctx = LineIndex;
61 type Output = Range; 61 type Output = Range;
62 62
63 fn conv_with(&self, line_index: &LineIndex) -> Range { 63 fn conv_with(self, line_index: &LineIndex) -> Range {
64 Range::new( 64 Range::new(
65 self.start().conv_with(line_index), 65 self.start().conv_with(line_index),
66 self.end().conv_with(line_index), 66 self.end().conv_with(line_index),
@@ -72,10 +72,70 @@ impl ConvWith for Range {
72 type Ctx = LineIndex; 72 type Ctx = LineIndex;
73 type Output = TextRange; 73 type Output = TextRange;
74 74
75 fn conv_with(&self, line_index: &LineIndex) -> TextRange { 75 fn conv_with(self, line_index: &LineIndex) -> TextRange {
76 TextRange::from_to( 76 TextRange::from_to(
77 self.start.conv_with(line_index), 77 self.start.conv_with(line_index),
78 self.end.conv_with(line_index), 78 self.end.conv_with(line_index),
79 ) 79 )
80 } 80 }
81} 81}
82
83impl ConvWith for Edit {
84 type Ctx = LineIndex;
85 type Output = Vec<TextEdit>;
86
87 fn conv_with(self, line_index: &LineIndex) -> Vec<TextEdit> {
88 self.into_atoms()
89 .into_iter()
90 .map_conv_with(line_index)
91 .collect()
92 }
93}
94
95impl ConvWith for AtomEdit {
96 type Ctx = LineIndex;
97 type Output = TextEdit;
98
99 fn conv_with(self, line_index: &LineIndex) -> TextEdit {
100 TextEdit {
101 range: self.delete.conv_with(line_index),
102 new_text: self.insert,
103 }
104 }
105}
106
107
108pub trait MapConvWith<'a>: Sized {
109 type Ctx;
110 type Output;
111
112 fn map_conv_with(self, ctx: &'a Self::Ctx) -> ConvWithIter<'a, Self, Self::Ctx> {
113 ConvWithIter { iter: self, ctx }
114 }
115}
116
117impl<'a, I> MapConvWith<'a> for I
118 where I: Iterator,
119 I::Item: ConvWith
120{
121 type Ctx = <I::Item as ConvWith>::Ctx;
122 type Output = <I::Item as ConvWith>::Output;
123}
124
125pub struct ConvWithIter<'a, I, Ctx: 'a> {
126 iter: I,
127 ctx: &'a Ctx,
128}
129
130impl<'a, I, Ctx> Iterator for ConvWithIter<'a, I, Ctx>
131 where
132 I: Iterator,
133 I::Item: ConvWith<Ctx=Ctx>,
134{
135 type Item = <I::Item as ConvWith>::Output;
136
137 fn next(&mut self) -> Option<Self::Item> {
138 self.iter.next().map(|item| item.conv_with(self.ctx))
139 }
140}
141