1use std::fmt;
4use std::sync::Arc;
5
6use rustc_hash::FxHashSet;
7use serde::de::{DeserializeSeed, Error as DeserializeError, MapAccess, SeqAccess, Visitor};
8use serde::{Deserialize, Deserializer};
9
10use super::builder::ResolutionReportLimits;
11use super::definition::SymbolDefinition;
12use super::error::ReportCollection;
13use super::record::ResolutionRecord;
14use super::reference::SymbolReference;
15use super::report::{ResolutionReport, ResolutionTier};
16use super::span::SourceSpan;
17use super::unit::ResolutionUnit;
18use super::validate::validate;
19use super::wire_field::ReportField;
20use super::wire_sequence::LimitedSequenceDecoder;
21
22const REPORT_FIELDS: &[&str] = &["tier", "units", "definitions", "references", "resolutions"];
23
24pub(super) fn deserialize_with_limits<'de, D>(
26 deserializer: D,
27 limits: ResolutionReportLimits,
28) -> Result<ResolutionReport, D::Error>
29where
30 D: Deserializer<'de>,
31{
32 WireReportDecoder { limits }.deserialize(deserializer)
33}
34
35impl<'de> Deserialize<'de> for ResolutionReport {
36 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
37 where
38 D: Deserializer<'de>,
39 {
40 deserialize_with_limits(deserializer, ResolutionReportLimits::default())
41 }
42}
43
44struct WireReportDecoder {
46 limits: ResolutionReportLimits,
47}
48
49impl<'de> DeserializeSeed<'de> for WireReportDecoder {
50 type Value = ResolutionReport;
51
52 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
53 where
54 D: Deserializer<'de>,
55 {
56 deserializer.deserialize_struct("ResolutionReport", REPORT_FIELDS, self)
57 }
58}
59
60impl<'de> Visitor<'de> for WireReportDecoder {
61 type Value = ResolutionReport;
62
63 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
64 formatter.write_str("a resolution report")
65 }
66
67 fn visit_seq<A>(self, mut sequence: A) -> Result<Self::Value, A::Error>
68 where
69 A: SeqAccess<'de>,
70 {
71 let tier = require_next(&mut sequence, "tier")?;
72 let units = require_next_seed(
73 &mut sequence,
74 LimitedSequenceDecoder::new(self.limits.max_units, ReportCollection::Units),
75 "units",
76 )?;
77 let definitions = require_next_seed(
78 &mut sequence,
79 LimitedSequenceDecoder::new(self.limits.max_definitions, ReportCollection::Definitions),
80 "definitions",
81 )?;
82 let references = require_next_seed(
83 &mut sequence,
84 LimitedSequenceDecoder::new(self.limits.max_references, ReportCollection::References),
85 "references",
86 )?;
87 let resolutions = require_next_seed(
88 &mut sequence,
89 LimitedSequenceDecoder::new(self.limits.max_references, ReportCollection::Resolutions),
90 "resolutions",
91 )?;
92 finish_report(tier, units, definitions, references, resolutions)
93 }
94
95 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
96 where
97 A: MapAccess<'de>,
98 {
99 let mut tier = None;
100 let mut units = None;
101 let mut definitions = None;
102 let mut references = None;
103 let mut resolutions = None;
104
105 while let Some(field) = map.next_key()? {
106 match field {
107 ReportField::Tier => {
108 reject_duplicate(&tier, "tier")?;
109 tier = Some(map.next_value()?);
110 }
111 ReportField::Units => {
112 reject_duplicate(&units, "units")?;
113 units = Some(map.next_value_seed(LimitedSequenceDecoder::new(
114 self.limits.max_units,
115 ReportCollection::Units,
116 ))?);
117 }
118 ReportField::Definitions => {
119 reject_duplicate(&definitions, "definitions")?;
120 definitions = Some(map.next_value_seed(LimitedSequenceDecoder::new(
121 self.limits.max_definitions,
122 ReportCollection::Definitions,
123 ))?);
124 }
125 ReportField::References => {
126 reject_duplicate(&references, "references")?;
127 references = Some(map.next_value_seed(LimitedSequenceDecoder::new(
128 self.limits.max_references,
129 ReportCollection::References,
130 ))?);
131 }
132 ReportField::Resolutions => {
133 reject_duplicate(&resolutions, "resolutions")?;
134 resolutions = Some(map.next_value_seed(LimitedSequenceDecoder::new(
135 self.limits.max_references,
136 ReportCollection::Resolutions,
137 ))?);
138 }
139 }
140 }
141
142 finish_report(
143 require_field(tier, "tier")?,
144 require_field(units, "units")?,
145 require_field(definitions, "definitions")?,
146 require_field(references, "references")?,
147 require_field(resolutions, "resolutions")?,
148 )
149 }
150}
151
152fn finish_report<E>(
153 tier: ResolutionTier,
154 units: Box<[ResolutionUnit]>,
155 mut definitions: Box<[SymbolDefinition]>,
156 mut references: Box<[SymbolReference]>,
157 resolutions: Box<[ResolutionRecord]>,
158) -> Result<ResolutionReport, E>
159where
160 E: DeserializeError,
161{
162 intern_paths(&mut definitions, &mut references);
163 let report = ResolutionReport::new(tier, units, definitions, references, resolutions);
164 validate(&report).map_err(E::custom)?;
165 Ok(report)
166}
167
168fn require_next<'de, A, T>(sequence: &mut A, name: &'static str) -> Result<T, A::Error>
169where
170 A: SeqAccess<'de>,
171 T: Deserialize<'de>,
172{
173 sequence
174 .next_element()?
175 .ok_or_else(|| A::Error::missing_field(name))
176}
177
178fn require_next_seed<'de, A, S>(
179 sequence: &mut A,
180 seed: S,
181 name: &'static str,
182) -> Result<S::Value, A::Error>
183where
184 A: SeqAccess<'de>,
185 S: DeserializeSeed<'de>,
186{
187 sequence
188 .next_element_seed(seed)?
189 .ok_or_else(|| A::Error::missing_field(name))
190}
191
192fn reject_duplicate<T, E>(field: &Option<T>, name: &'static str) -> Result<(), E>
193where
194 E: DeserializeError,
195{
196 match field.is_some() {
197 true => Err(E::duplicate_field(name)),
198 false => Ok(()),
199 }
200}
201
202fn require_field<T, E>(field: Option<T>, name: &'static str) -> Result<T, E>
203where
204 E: DeserializeError,
205{
206 field.ok_or_else(|| E::missing_field(name))
207}
208
209fn intern_paths(definitions: &mut [SymbolDefinition], references: &mut [SymbolReference]) {
216 let mut paths: FxHashSet<Arc<str>> = FxHashSet::default();
217 for definition in definitions {
218 intern(&mut paths, definition.span_mut());
219 }
220 for reference in references {
221 intern(&mut paths, reference.span_mut());
222 }
223}
224
225fn intern(paths: &mut FxHashSet<Arc<str>>, span: &mut SourceSpan) {
226 let canonical = paths.get(span.file()).map(Arc::clone);
227 match canonical {
228 Some(canonical) => span.adopt_file(canonical),
229 None => {
230 paths.insert(Arc::clone(span.shared_file()));
231 }
232 }
233}