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
use crate::ra_ap_syntax::{
    ast::{Name, NameRef, Path, PathSegment},
    AstNode,
};

use ra_ap_text_edit::{TextEdit, TextEditBuilder, TextRange, TextSize};

#[derive(Default, Debug, Clone)]
pub struct Upgrader {
    edit: TextEditBuilder,
}

pub trait ToTextRange {
    fn to(self) -> TextRange;
}

impl ToTextRange for TextRange {
    fn to(self) -> TextRange {
        self
    }
}

impl ToTextRange for Option<Path> {
    fn to(self) -> TextRange {
        self.unwrap().segment().to()
    }
}

impl ToTextRange for Option<PathSegment> {
    fn to(self) -> TextRange {
        self.unwrap().name_ref().to()
    }
}

impl ToTextRange for Option<NameRef> {
    fn to(self) -> TextRange {
        self.unwrap().syntax().text_range()
    }
}

impl ToTextRange for Option<Name> {
    fn to(self) -> TextRange {
        self.unwrap().syntax().text_range()
    }
}

impl Upgrader {
    pub fn replace<T, S>(&mut self, range: T, replace_with: S)
    where
        T: ToTextRange,
        S: Into<String>,
    {
        self.edit.replace(range.to(), replace_with.into())
    }

    pub fn delete<T>(&mut self, range: T)
    where
        T: ToTextRange,
    {
        self.edit.delete(range.to())
    }

    pub fn insert<S>(&mut self, offset: TextSize, text: S)
    where
        S: Into<String>,
    {
        self.edit.insert(offset, text.into())
    }

    pub fn add_dep(&mut self) {}

    pub fn add_feature(&mut self) {}

    pub(crate) fn finish(&mut self) -> TextEdit {
        let edit = self.edit.clone().finish();
        self.edit = TextEditBuilder::default();
        edit
    }
}