#[derive(Debug, Clone)]
pub struct Assist {
- id: AssistId,
+ pub id: AssistId,
/// Short description of the assist, as shown in the UI.
label: String,
- group: Option<GroupLabel>,
+ pub group: Option<GroupLabel>,
/// Target ranges are used to sort assists: the smaller the target range,
/// the more specific assist is, and so it should be sorted first.
- target: TextRange,
+ pub target: TextRange,
}
#[derive(Debug, Clone)]
}
impl Assist {
+ fn new(id: AssistId, label: String, group: Option<GroupLabel>, target: TextRange) -> Assist {
+ assert!(label.starts_with(char::is_uppercase));
+ Assist { id, label, group, target }
+ }
+
/// Return all the assists applicable at the given position.
///
/// Assists are returned in the "unresolved" state, that is only labels are
acc.finish_resolved()
}
- pub(crate) fn new(
- id: AssistId,
- label: String,
- group: Option<GroupLabel>,
- target: TextRange,
- ) -> Assist {
- assert!(label.starts_with(|c: char| c.is_uppercase()));
- Assist { id, label, group, target }
- }
-
- pub fn id(&self) -> AssistId {
- self.id
- }
-
- pub fn label(&self) -> String {
- self.label.clone()
- }
-
- pub fn group(&self) -> Option<GroupLabel> {
- self.group.clone()
- }
-
- pub fn target(&self) -> TextRange {
- self.target
+ pub fn label(&self) -> &str {
+ self.label.as_str()
}
}
.map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect());
let assists = snap.analysis.resolved_assists(&snap.config.assist, frange)?;
- let (id_string, index) = split_once(¶ms.id, ':').unwrap();
+ let (id, index) = split_once(¶ms.id, ':').unwrap();
let index = index.parse::<usize>().unwrap();
let assist = &assists[index];
- assert!(assist.assist.id().0 == id_string);
+ assert!(assist.assist.id.0 == id);
Ok(to_proto::resolved_code_action(&snap, assist.clone())?.edit)
}
index: usize,
) -> Result<lsp_ext::CodeAction> {
let res = lsp_ext::CodeAction {
- title: assist.label(),
- id: Some(format!("{}:{}", assist.id().0.to_owned(), index.to_string())),
- group: assist.group().filter(|_| snap.config.client_caps.code_action_group).map(|gr| gr.0),
- kind: Some(code_action_kind(assist.id().1)),
+ title: assist.label().to_string(),
+ id: Some(format!("{}:{}", assist.id.0, index.to_string())),
+ group: assist.group.filter(|_| snap.config.client_caps.code_action_group).map(|gr| gr.0),
+ kind: Some(code_action_kind(assist.id.1)),
edit: None,
is_preferred: None,
};
}
```
+# Getters & Setters
+
+If a field can have any value without breaking invariants, make the field public.
+Conversely, if there is an invariant, document it, enforce it in the "constructor" function, make the field private, and provide a getter.
+Never provide setters.
+
+Getters should return borrowed data:
+
+```
+struct Person {
+ // Invariant: never empty
+ first_name: String,
+ middle_name: Option<String>
+}
+
+// Good
+impl Person {
+ fn first_name(&self) -> &str { self.first_name.as_str() }
+ fn middle_name(&self) -> Option<&str> { self.middle_name.as_ref() }
+}
+
+// Not as good
+impl Person {
+ fn first_name(&self) -> String { self.first_name.clone() }
+ fn middle_name(&self) -> &Option<String> { &self.middle_name }
+}
+```
+
+
# Premature Pessimization
Avoid writing code which is slower than it needs to be.