1use crate::BuiltinSignature;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
13pub enum MethodReceiver {
14 String,
15 List,
16 Set,
17 Dict,
18 Range,
19 Iter,
20 Generator,
21}
22
23impl MethodReceiver {
24 pub const ALL: [MethodReceiver; 7] = [
25 MethodReceiver::String,
26 MethodReceiver::List,
27 MethodReceiver::Set,
28 MethodReceiver::Dict,
29 MethodReceiver::Range,
30 MethodReceiver::Iter,
31 MethodReceiver::Generator,
32 ];
33
34 pub const fn type_name(self) -> &'static str {
36 match self {
37 MethodReceiver::String => "string",
38 MethodReceiver::List => "list",
39 MethodReceiver::Set => "set",
40 MethodReceiver::Dict => "dict",
41 MethodReceiver::Range => "range",
42 MethodReceiver::Iter => "iter",
43 MethodReceiver::Generator => "generator",
44 }
45 }
46
47 pub const fn receiver_type_params(self) -> &'static [&'static str] {
51 match self {
52 MethodReceiver::List
53 | MethodReceiver::Set
54 | MethodReceiver::Iter
55 | MethodReceiver::Generator => &["T"],
56 MethodReceiver::Dict => &["K", "V"],
57 MethodReceiver::String | MethodReceiver::Range => &[],
58 }
59 }
60}
61
62#[derive(Debug, Clone, Copy, PartialEq, Eq)]
64pub enum MethodEffect {
65 Pure,
68 Mutating,
72}
73
74#[derive(Debug, Clone, Copy)]
77pub struct MethodDescriptor {
78 pub receiver: MethodReceiver,
79 pub signature: BuiltinSignature,
82 pub effect: MethodEffect,
83 pub doc: &'static str,
84}
85
86impl MethodDescriptor {
87 pub const fn pure(
88 receiver: MethodReceiver,
89 signature: BuiltinSignature,
90 doc: &'static str,
91 ) -> Self {
92 Self {
93 receiver,
94 signature,
95 effect: MethodEffect::Pure,
96 doc,
97 }
98 }
99
100 pub const fn mutating(
101 receiver: MethodReceiver,
102 signature: BuiltinSignature,
103 doc: &'static str,
104 ) -> Self {
105 Self {
106 receiver,
107 signature,
108 effect: MethodEffect::Mutating,
109 doc,
110 }
111 }
112
113 pub const fn name(&self) -> &'static str {
114 self.signature.name
115 }
116
117 pub const fn is_mutating(&self) -> bool {
118 matches!(self.effect, MethodEffect::Mutating)
119 }
120}
121
122#[derive(Debug, Clone, Copy, PartialEq, Eq)]
124pub enum MethodMigration {
125 Rename(&'static str),
127 AppendingToPush,
130 MutatingWhenSelfAssigned {
133 mutating: &'static str,
134 guidance: &'static str,
135 },
136 Manual(&'static str),
138}
139
140#[derive(Debug, Clone, Copy)]
142pub struct RemovedMethod {
143 pub receiver: MethodReceiver,
144 pub name: &'static str,
145 pub migration: MethodMigration,
146}
147
148impl RemovedMethod {
149 pub const fn renamed(receiver: MethodReceiver, name: &'static str, to: &'static str) -> Self {
150 Self {
151 receiver,
152 name,
153 migration: MethodMigration::Rename(to),
154 }
155 }
156
157 pub const fn mutating_when_self_assigned(
158 receiver: MethodReceiver,
159 name: &'static str,
160 mutating: &'static str,
161 guidance: &'static str,
162 ) -> Self {
163 Self {
164 receiver,
165 name,
166 migration: MethodMigration::MutatingWhenSelfAssigned { mutating, guidance },
167 }
168 }
169
170 pub const fn manual(
171 receiver: MethodReceiver,
172 name: &'static str,
173 guidance: &'static str,
174 ) -> Self {
175 Self {
176 receiver,
177 name,
178 migration: MethodMigration::Manual(guidance),
179 }
180 }
181
182 pub fn repair_hint(&self) -> String {
184 match self.migration {
185 MethodMigration::Rename(to) => format!("did you mean `{to}`?"),
186 MethodMigration::AppendingToPush => {
187 "use `xs.push(v)` to append in place, or `xs + [v]` for a new list".to_string()
188 }
189 MethodMigration::MutatingWhenSelfAssigned { guidance, .. }
190 | MethodMigration::Manual(guidance) => guidance.to_string(),
191 }
192 }
193}