ide_completion/render/
union_literal.rs1use hir::{HirDisplay, Name, StructKind};
4use ide_db::SymbolKind;
5use itertools::Itertools;
6use syntax::ToSmolStr;
7
8use crate::{
9 CompletionItem, CompletionItemKind,
10 render::{
11 RenderContext,
12 variant::{format_literal_label, format_literal_lookup, visible_fields},
13 },
14};
15
16pub(crate) fn render_union_literal(
17 ctx: RenderContext<'_>,
18 un: hir::Union,
19 path: Option<hir::ModPath>,
20 local_name: Option<Name>,
21) -> Option<CompletionItem> {
22 let name = local_name.unwrap_or_else(|| un.name(ctx.db()));
23
24 let (qualified_name, escaped_qualified_name) = match path {
25 Some(p) => (
26 p.display_verbatim(ctx.db()).to_smolstr(),
27 p.display(ctx.db(), ctx.completion.edition).to_smolstr(),
28 ),
29 None => (
30 name.as_str().to_smolstr(),
31 name.display(ctx.db(), ctx.completion.edition).to_smolstr(),
32 ),
33 };
34 let label = format_literal_label(
35 &name.display_no_db(ctx.completion.edition).to_smolstr(),
36 StructKind::Record,
37 ctx.snippet_cap(),
38 );
39 let lookup = format_literal_lookup(
40 &name.display_no_db(ctx.completion.edition).to_smolstr(),
41 StructKind::Record,
42 );
43 let mut item = CompletionItem::new(
44 CompletionItemKind::SymbolKind(SymbolKind::Union),
45 ctx.source_range(),
46 label,
47 ctx.completion.edition,
48 );
49
50 item.lookup_by(lookup);
51
52 let fields = un.fields(ctx.db());
53 let (fields, fields_omitted) = visible_fields(ctx.completion, &fields, un)?;
54
55 if fields.is_empty() {
56 return None;
57 }
58
59 let literal = if ctx.snippet_cap().is_some() {
60 format!(
61 "{} {{ ${{1|{}|}}: ${{2:()}} }}$0",
62 escaped_qualified_name,
63 fields
64 .iter()
65 .map(|field| field
66 .name(ctx.db())
67 .display_no_db(ctx.completion.edition)
68 .to_smolstr())
69 .format(",")
70 )
71 } else {
72 format!(
73 "{} {{ {} }}",
74 escaped_qualified_name,
75 fields.iter().format_with(", ", |field, f| {
76 f(&format_args!(
77 "{}: ()",
78 field.name(ctx.db()).display(ctx.db(), ctx.completion.edition)
79 ))
80 })
81 )
82 };
83
84 let detail = format!(
85 "{} {{ {}{} }}",
86 qualified_name,
87 fields.iter().format_with(", ", |field, f| {
88 f(&format_args!(
89 "{}: {}",
90 field.name(ctx.db()).display(ctx.db(), ctx.completion.edition),
91 field.ty(ctx.db()).display(ctx.db(), ctx.completion.display_target)
92 ))
93 }),
94 if fields_omitted { ", .." } else { "" }
95 );
96
97 item.set_documentation(ctx.docs(un))
98 .set_deprecated(ctx.is_deprecated(un))
99 .detail(detail)
100 .set_relevance(ctx.completion_relevance());
101
102 match ctx.snippet_cap() {
103 Some(snippet_cap) => item.insert_snippet(snippet_cap, literal).trigger_call_info(),
104 None => item.insert_text(literal),
105 };
106
107 Some(item.build(ctx.db()))
108}