1#![allow(clippy::unnecessary_wraps)] // Needed for macro
2
3use capnp::{text, text_list};
4use ecow::EcoString;
5use itertools::Itertools;
6
7use crate::{
8 Result,
9 ast::{
10 BitArrayOption, BitArraySegment, CallArg, Constant, Publicity, SrcSpan, TypedConstant,
11 TypedConstantBitArraySegment, TypedConstantBitArraySegmentOption,
12 },
13 build::Origin,
14 line_numbers::{Character, LineNumbers},
15 reference::{Reference, ReferenceKind, ReferenceMap},
16 schema_capnp::{self as schema, *},
17 type_::{
18 self, AccessorsMap, Deprecation, FieldMap, ModuleInterface, Opaque, RecordAccessor,
19 References, Type, TypeAliasConstructor, TypeConstructor, TypeValueConstructor,
20 TypeValueConstructorField, TypeVariantConstructors, ValueConstructor,
21 ValueConstructorVariant,
22 expression::{Implementations, Purity},
23 },
24 uid::UniqueIdGenerator,
25};
26use std::{collections::HashMap, collections::HashSet, io::BufRead, sync::Arc};
27
28macro_rules! read_vec {
29 ($reader:expr, $self:expr, $method:ident) => {{
30 let reader = $reader;
31 let mut vec = Vec::with_capacity(reader.len() as usize);
32 for reader in reader.into_iter() {
33 let value = $self.$method(&reader)?;
34 vec.push(value);
35 }
36 vec
37 }};
38}
39
40macro_rules! read_hashmap {
41 ($reader:expr, $self:expr, $method:ident) => {{
42 let reader = $reader;
43 let mut map = HashMap::with_capacity(reader.len() as usize);
44 for prop in reader.into_iter() {
45 let name = $self.string(prop.get_key()?)?;
46 let values = $self.$method(&prop.get_value()?.into())?;
47 let _ = map.insert(name, values);
48 }
49 map
50 }};
51}
52
53#[derive(Debug)]
54pub struct ModuleDecoder {
55 ids: UniqueIdGenerator,
56 type_var_id_map: HashMap<u64, u64>,
57}
58
59impl ModuleDecoder {
60 pub fn new(ids: UniqueIdGenerator) -> Self {
61 Self {
62 ids,
63 type_var_id_map: Default::default(),
64 }
65 }
66
67 pub fn read(&mut self, reader: impl BufRead) -> Result<ModuleInterface> {
68 let message_reader =
69 capnp::serialize_packed::read_message(reader, capnp::message::ReaderOptions::new())?;
70 let reader = message_reader.get_root::<module::Reader<'_>>()?;
71
72 Ok(ModuleInterface {
73 name: self.string(reader.get_name()?)?,
74 package: self.string(reader.get_package()?)?,
75 is_internal: reader.get_is_internal(),
76 origin: Origin::Src,
77 values: read_hashmap!(reader.get_values()?, self, value_constructor),
78 types: read_hashmap!(reader.get_types()?, self, type_constructor),
79 types_value_constructors: read_hashmap!(
80 reader.get_types_constructors()?,
81 self,
82 type_variants_constructors
83 ),
84 accessors: read_hashmap!(reader.get_accessors()?, self, accessors_map),
85 line_numbers: self.line_numbers(&reader.get_line_numbers()?)?,
86 src_path: self.str(reader.get_src_path()?)?.into(),
87 warnings: vec![],
88 minimum_required_version: self.version(&reader.get_required_version()?),
89 type_aliases: read_hashmap!(reader.get_type_aliases()?, self, type_alias_constructor),
90 documentation: self.string_list(reader.get_documentation()?)?,
91 contains_echo: reader.get_contains_echo(),
92 references: self.references(reader.get_references()?)?,
93 })
94 }
95
96 fn string(&self, reader: text::Reader<'_>) -> Result<EcoString> {
97 self.str(reader).map(|str| str.into())
98 }
99
100 fn string_list(&self, reader: text_list::Reader<'_>) -> Result<Vec<EcoString>> {
101 let mut vec = Vec::with_capacity(reader.len() as usize);
102 for reader in reader.into_iter() {
103 vec.push(self.string(reader?)?);
104 }
105 Ok(vec)
106 }
107
108 fn str<'a>(&self, reader: text::Reader<'a>) -> Result<&'a str> {
109 reader
110 .to_str()
111 .map_err(|_| capnp::Error::failed("String contains non-utf8 characters".into()).into())
112 }
113
114 fn references(&self, reader: references::Reader<'_>) -> Result<References> {
115 Ok(References {
116 imported_modules: self.string_set(reader.get_imported_modules()?)?,
117 value_references: self.reference_map(reader.get_value_references()?)?,
118 type_references: self.reference_map(reader.get_type_references()?)?,
119 })
120 }
121
122 fn string_set(&self, reader: text_list::Reader<'_>) -> Result<HashSet<EcoString>> {
123 let mut set = HashSet::with_capacity(reader.len() as usize);
124 for reader in reader.into_iter() {
125 let _ = set.insert(self.string(reader?)?);
126 }
127 Ok(set)
128 }
129
130 fn reference_map(
131 &self,
132 reader: capnp::struct_list::Reader<'_, reference_map::Owned>,
133 ) -> Result<ReferenceMap> {
134 let mut map = HashMap::with_capacity(reader.len() as usize);
135 for prop in reader.into_iter() {
136 let module = self.string(prop.get_module()?)?;
137 let name = self.string(prop.get_name()?)?;
138 let references = read_vec!(prop.get_references()?, self, reference);
139 let _ = map.insert((module, name), references);
140 }
141 Ok(map)
142 }
143
144 fn reference(&self, reader: &reference::Reader<'_>) -> Result<Reference> {
145 Ok(Reference {
146 location: self.src_span(&reader.get_location()?)?,
147 kind: self.reference_kind(&reader.get_kind()?)?,
148 })
149 }
150
151 fn reference_kind(&self, reader: &reference_kind::Reader<'_>) -> Result<ReferenceKind> {
152 use reference_kind::Which;
153 Ok(match reader.which()? {
154 Which::Qualified(_) => ReferenceKind::Qualified,
155 Which::Unqualified(_) => ReferenceKind::Unqualified,
156 Which::Import(_) => ReferenceKind::Import,
157 Which::Definition(_) => ReferenceKind::Definition,
158 Which::Alias(_) => ReferenceKind::Alias,
159 })
160 }
161
162 fn type_constructor(
163 &mut self,
164 reader: &type_constructor::Reader<'_>,
165 ) -> Result<TypeConstructor> {
166 let type_ = self.type_(&reader.get_type()?)?;
167 let deprecation = reader.get_deprecated()?;
168 let deprecation = if deprecation.is_empty() {
169 Deprecation::NotDeprecated
170 } else {
171 Deprecation::Deprecated {
172 message: self.string(deprecation)?,
173 }
174 };
175 Ok(TypeConstructor {
176 publicity: self.publicity(reader.get_publicity()?)?,
177 origin: self.src_span(&reader.get_origin()?)?,
178 module: self.string(reader.get_module()?)?,
179 parameters: read_vec!(reader.get_parameters()?, self, type_),
180 type_,
181 deprecation,
182 documentation: self.optional_string(self.str(reader.get_documentation()?)?),
183 })
184 }
185
186 fn type_alias_constructor(
187 &mut self,
188 reader: &type_alias_constructor::Reader<'_>,
189 ) -> Result<TypeAliasConstructor> {
190 let type_ = self.type_(&reader.get_type()?)?;
191 let deprecation = reader.get_deprecation()?;
192 let deprecation = if deprecation.is_empty() {
193 Deprecation::NotDeprecated
194 } else {
195 Deprecation::Deprecated {
196 message: self.string(deprecation)?,
197 }
198 };
199 Ok(TypeAliasConstructor {
200 publicity: self.publicity(reader.get_publicity()?)?,
201 origin: self.src_span(&reader.get_origin()?)?,
202 module: self.string(reader.get_module()?)?,
203 type_,
204 deprecation,
205 documentation: self.optional_string(self.str(reader.get_documentation()?)?),
206 arity: reader.get_arity() as usize,
207 })
208 }
209
210 fn type_(&mut self, reader: &schema::type_::Reader<'_>) -> Result<Arc<Type>> {
211 use schema::type_::Which;
212 match reader.which()? {
213 Which::App(reader) => self.type_app(&reader),
214 Which::Fn(reader) => self.type_fn(&reader),
215 Which::Tuple(reader) => self.type_tuple(&reader),
216 Which::Var(reader) => self.type_var(&reader),
217 }
218 }
219
220 fn type_app(&mut self, reader: &schema::type_::app::Reader<'_>) -> Result<Arc<Type>> {
221 let package = self.string(reader.get_package()?)?;
222 let module = self.string(reader.get_module()?)?;
223 let name = self.string(reader.get_name()?)?;
224 let args = read_vec!(&reader.get_parameters()?, self, type_);
225 let inferred_variant = self.inferred_variant(&reader.get_inferred_variant()?)?;
226
227 Ok(Arc::new(Type::Named {
228 publicity: Publicity::Public,
229 package,
230 module,
231 name,
232 args,
233 inferred_variant,
234 }))
235 }
236
237 fn type_fn(&mut self, reader: &schema::type_::fn_::Reader<'_>) -> Result<Arc<Type>> {
238 let return_ = self.type_(&reader.get_return()?)?;
239 let args = read_vec!(&reader.get_arguments()?, self, type_);
240 Ok(Arc::new(Type::Fn { args, return_ }))
241 }
242
243 fn type_tuple(&mut self, reader: &schema::type_::tuple::Reader<'_>) -> Result<Arc<Type>> {
244 let elements = read_vec!(&reader.get_elements()?, self, type_);
245 Ok(Arc::new(Type::Tuple { elements }))
246 }
247
248 fn type_var(&mut self, reader: &schema::type_::var::Reader<'_>) -> Result<Arc<Type>> {
249 let serialized_id = reader.get_id();
250 let id = self.get_or_insert_type_var_id(serialized_id);
251 Ok(type_::generic_var(id))
252 }
253
254 fn get_or_insert_type_var_id(&mut self, id: u64) -> u64 {
255 match self.type_var_id_map.get(&id) {
256 Some(&id) => id,
257 None => {
258 let new_id = self.ids.next();
259 let _ = self.type_var_id_map.insert(id, new_id);
260 new_id
261 }
262 }
263 }
264
265 fn type_variants_constructors(
266 &mut self,
267 reader: &types_variant_constructors::Reader<'_>,
268 ) -> Result<TypeVariantConstructors> {
269 let variants = reader
270 .get_variants()?
271 .iter()
272 .map(|r| self.type_value_constructor(&r))
273 .try_collect()?;
274 let type_parameters_ids = read_vec!(
275 reader.get_type_parameters_ids()?,
276 self,
277 type_variant_constructor_type_parameter_id
278 );
279 let opaque = if reader.get_opaque() {
280 Opaque::Opaque
281 } else {
282 Opaque::NotOpaque
283 };
284
285 Ok(TypeVariantConstructors {
286 variants,
287 type_parameters_ids,
288 opaque,
289 })
290 }
291
292 fn type_variant_constructor_type_parameter_id(&mut self, i: &u16) -> Result<u64> {
293 Ok(self.get_or_insert_type_var_id(*i as u64))
294 }
295
296 fn type_value_constructor(
297 &mut self,
298 reader: &type_value_constructor::Reader<'_>,
299 ) -> Result<TypeValueConstructor> {
300 Ok(TypeValueConstructor {
301 name: self.string(reader.get_name()?)?,
302 parameters: read_vec!(
303 reader.get_parameters()?,
304 self,
305 type_value_constructor_parameter
306 ),
307 documentation: self.optional_string(self.str(reader.get_documentation()?)?),
308 })
309 }
310
311 fn type_value_constructor_parameter(
312 &mut self,
313 reader: &type_value_constructor_parameter::Reader<'_>,
314 ) -> Result<TypeValueConstructorField> {
315 Ok(TypeValueConstructorField {
316 type_: self.type_(&reader.get_type()?)?,
317 label: self.optional_string(self.str(reader.get_label()?)?),
318 })
319 }
320
321 fn inferred_variant(&mut self, reader: &inferred_variant::Reader<'_>) -> Result<Option<u16>> {
322 use schema::inferred_variant::Which;
323 match reader.which()? {
324 Which::Unknown(_) => Ok(None),
325 Which::Inferred(variant) => Ok(Some(variant)),
326 }
327 }
328
329 fn value_constructor(
330 &mut self,
331 reader: &value_constructor::Reader<'_>,
332 ) -> Result<ValueConstructor> {
333 let type_ = self.type_(&reader.get_type()?)?;
334 let variant = self.value_constructor_variant(&reader.get_variant()?)?;
335 let publicity = self.publicity(reader.get_publicity()?)?;
336 let deprecation = reader.get_deprecated()?;
337 let deprecation = if deprecation.is_empty() {
338 Deprecation::NotDeprecated
339 } else {
340 Deprecation::Deprecated {
341 message: self.string(deprecation)?,
342 }
343 };
344 Ok(ValueConstructor {
345 deprecation,
346 publicity,
347 type_,
348 variant,
349 })
350 }
351
352 fn publicity(&self, reader: publicity::Reader<'_>) -> Result<Publicity> {
353 match reader.which()? {
354 publicity::Which::Public(()) => Ok(Publicity::Public),
355 publicity::Which::Private(()) => Ok(Publicity::Private),
356 publicity::Which::Internal(reader) => match reader?.which()? {
357 option::Which::None(()) => Ok(Publicity::Internal {
358 attribute_location: None,
359 }),
360 option::Which::Some(reader) => Ok(Publicity::Internal {
361 attribute_location: Some(self.src_span(&reader?)?),
362 }),
363 },
364 }
365 }
366
367 fn constant(&mut self, reader: &constant::Reader<'_>) -> Result<TypedConstant> {
368 use constant::Which;
369 match reader.which()? {
370 Which::Int(reader) => Ok(self.constant_int(self.str(reader?)?)),
371 Which::Float(reader) => Ok(self.constant_float(self.str(reader?)?)),
372 Which::String(reader) => Ok(self.constant_string(self.str(reader?)?)),
373 Which::Tuple(reader) => self.constant_tuple(&reader?),
374 Which::List(reader) => self.constant_list(&reader),
375 Which::Record(reader) => self.constant_record(&reader),
376 Which::BitArray(reader) => self.constant_bit_array(&reader?),
377 Which::Var(reader) => self.constant_var(&reader),
378 Which::StringConcatenation(reader) => self.constant_string_concatenation(&reader),
379 }
380 }
381
382 fn constant_int(&self, value: &str) -> TypedConstant {
383 Constant::Int {
384 location: Default::default(),
385 value: value.into(),
386 int_value: crate::parse::parse_int_value(value).expect("int value to parse as bigint"),
387 }
388 }
389
390 fn constant_float(&self, value: &str) -> TypedConstant {
391 Constant::Float {
392 location: Default::default(),
393 value: value.into(),
394 }
395 }
396
397 fn constant_string(&self, value: &str) -> TypedConstant {
398 Constant::String {
399 location: Default::default(),
400 value: value.into(),
401 }
402 }
403
404 fn constant_tuple(
405 &mut self,
406 reader: &capnp::struct_list::Reader<'_, constant::Owned>,
407 ) -> Result<TypedConstant> {
408 Ok(Constant::Tuple {
409 location: Default::default(),
410 elements: read_vec!(reader, self, constant),
411 })
412 }
413
414 fn constant_list(&mut self, reader: &constant::list::Reader<'_>) -> Result<TypedConstant> {
415 let type_ = self.type_(&reader.get_type()?)?;
416 Ok(Constant::List {
417 location: Default::default(),
418 elements: read_vec!(reader.get_elements()?, self, constant),
419 type_,
420 })
421 }
422
423 fn constant_record(&mut self, reader: &constant::record::Reader<'_>) -> Result<TypedConstant> {
424 let type_ = self.type_(&reader.get_type()?)?;
425 let tag = self.string(reader.get_tag()?)?;
426 let args = read_vec!(reader.get_args()?, self, constant_call_arg);
427 Ok(Constant::Record {
428 location: Default::default(),
429 module: Default::default(),
430 name: Default::default(),
431 args,
432 tag,
433 type_,
434 field_map: None,
435 record_constructor: None,
436 })
437 }
438
439 fn constant_call_arg(
440 &mut self,
441 reader: &constant::Reader<'_>,
442 ) -> Result<CallArg<TypedConstant>> {
443 Ok(CallArg {
444 implicit: None,
445 label: Default::default(),
446 location: Default::default(),
447 value: self.constant(reader)?,
448 })
449 }
450
451 fn constant_bit_array(
452 &mut self,
453 reader: &capnp::struct_list::Reader<'_, bit_array_segment::Owned>,
454 ) -> Result<TypedConstant> {
455 Ok(Constant::BitArray {
456 location: Default::default(),
457 segments: read_vec!(reader, self, bit_array_segment),
458 })
459 }
460
461 fn constant_var(&mut self, reader: &constant::var::Reader<'_>) -> Result<TypedConstant> {
462 let type_ = self.type_(&reader.get_type()?)?;
463 let module = self.optional_string(self.str(reader.get_module()?)?);
464 let name = reader.get_name()?;
465 let constructor = self.value_constructor(&reader.get_constructor()?)?;
466 Ok(Constant::Var {
467 location: Default::default(),
468 module: module.map(|module| (module, Default::default())),
469 name: self.string(name)?,
470 constructor: Some(Box::from(constructor)),
471 type_,
472 })
473 }
474
475 fn constant_string_concatenation(
476 &mut self,
477 reader: &constant::string_concatenation::Reader<'_>,
478 ) -> Result<TypedConstant> {
479 Ok(Constant::StringConcatenation {
480 location: Default::default(),
481 left: Box::new(self.constant(&reader.get_left()?)?),
482 right: Box::new(self.constant(&reader.get_right()?)?),
483 })
484 }
485
486 fn bit_array_segment(
487 &mut self,
488 reader: &bit_array_segment::Reader<'_>,
489 ) -> Result<TypedConstantBitArraySegment> {
490 Ok(BitArraySegment {
491 location: Default::default(),
492 type_: self.type_(&reader.get_type()?)?,
493 value: Box::new(self.constant(&reader.get_value()?)?),
494 options: read_vec!(reader.get_options()?, self, bit_array_segment_option),
495 })
496 }
497
498 fn bit_array_segment_option(
499 &mut self,
500 reader: &bit_array_segment_option::Reader<'_>,
501 ) -> Result<TypedConstantBitArraySegmentOption> {
502 use bit_array_segment_option::Which;
503 Ok(match reader.which()? {
504 Which::Bytes(_) => BitArrayOption::Bytes {
505 location: Default::default(),
506 },
507 Which::Integer(_) => BitArrayOption::Int {
508 location: Default::default(),
509 },
510 Which::Float(_) => BitArrayOption::Float {
511 location: Default::default(),
512 },
513 Which::Bits(_) => BitArrayOption::Bits {
514 location: Default::default(),
515 },
516 Which::Utf8(_) => BitArrayOption::Utf8 {
517 location: Default::default(),
518 },
519 Which::Utf16(_) => BitArrayOption::Utf16 {
520 location: Default::default(),
521 },
522 Which::Utf32(_) => BitArrayOption::Utf32 {
523 location: Default::default(),
524 },
525 Which::Utf8Codepoint(_) => BitArrayOption::Utf8Codepoint {
526 location: Default::default(),
527 },
528 Which::Utf16Codepoint(_) => BitArrayOption::Utf16Codepoint {
529 location: Default::default(),
530 },
531 Which::Utf32Codepoint(_) => BitArrayOption::Utf32Codepoint {
532 location: Default::default(),
533 },
534 Which::Signed(_) => BitArrayOption::Signed {
535 location: Default::default(),
536 },
537 Which::Unsigned(_) => BitArrayOption::Unsigned {
538 location: Default::default(),
539 },
540 Which::Big(_) => BitArrayOption::Big {
541 location: Default::default(),
542 },
543 Which::Little(_) => BitArrayOption::Little {
544 location: Default::default(),
545 },
546 Which::Native(_) => BitArrayOption::Native {
547 location: Default::default(),
548 },
549 Which::Size(reader) => BitArrayOption::Size {
550 location: Default::default(),
551 short_form: reader.get_short_form(),
552 value: Box::new(self.constant(&reader.get_value()?)?),
553 },
554 Which::Unit(reader) => BitArrayOption::Unit {
555 location: Default::default(),
556 value: reader.get_value(),
557 },
558 })
559 }
560
561 fn value_constructor_variant(
562 &mut self,
563 reader: &value_constructor_variant::Reader<'_>,
564 ) -> Result<ValueConstructorVariant> {
565 use value_constructor_variant::Which;
566 match reader.which()? {
567 Which::ModuleConstant(reader) => self.module_constant_variant(&reader),
568 Which::ModuleFn(reader) => self.module_fn_variant(&reader),
569 Which::Record(reader) => self.record(&reader),
570 }
571 }
572
573 fn module_constant_variant(
574 &mut self,
575 reader: &value_constructor_variant::module_constant::Reader<'_>,
576 ) -> Result<ValueConstructorVariant> {
577 Ok(ValueConstructorVariant::ModuleConstant {
578 documentation: self.optional_string(self.str(reader.get_documentation()?)?),
579 location: self.src_span(&reader.get_location()?)?,
580 literal: self.constant(&reader.get_literal()?)?,
581 module: self.string(reader.get_module()?)?,
582 name: self.string(reader.get_name()?)?,
583 implementations: self.implementations(reader.get_implementations()?),
584 })
585 }
586
587 fn optional_string(&self, str: &str) -> Option<EcoString> {
588 if str.is_empty() {
589 None
590 } else {
591 Some(str.into())
592 }
593 }
594
595 fn src_span(&self, reader: &src_span::Reader<'_>) -> Result<SrcSpan> {
596 Ok(SrcSpan {
597 start: reader.get_start(),
598 end: reader.get_end(),
599 })
600 }
601
602 fn module_fn_variant(
603 &self,
604 reader: &value_constructor_variant::module_fn::Reader<'_>,
605 ) -> Result<ValueConstructorVariant> {
606 let purity = match reader.get_purity()?.which()? {
607 purity::Which::Pure(()) => Purity::Pure,
608 purity::Which::TrustedPure(()) => Purity::TrustedPure,
609 purity::Which::Impure(()) => Purity::Impure,
610 purity::Which::Unknown(()) => Purity::Unknown,
611 };
612
613 Ok(ValueConstructorVariant::ModuleFn {
614 name: self.string(reader.get_name()?)?,
615 module: self.string(reader.get_module()?)?,
616 arity: reader.get_arity() as usize,
617 field_map: self.field_map(&reader.get_field_map()?)?,
618 location: self.src_span(&reader.get_location()?)?,
619 documentation: self.optional_string(self.str(reader.get_documentation()?)?),
620 implementations: self.implementations(reader.get_implementations()?),
621 external_erlang: self.optional_external(reader.get_external_erlang()?)?,
622 external_javascript: self.optional_external(reader.get_external_javascript()?)?,
623 purity,
624 })
625 }
626
627 fn implementations(&self, reader: implementations::Reader<'_>) -> Implementations {
628 Implementations {
629 gleam: reader.get_gleam(),
630 uses_erlang_externals: reader.get_uses_erlang_externals(),
631 uses_javascript_externals: reader.get_uses_javascript_externals(),
632 can_run_on_erlang: reader.get_can_run_on_erlang(),
633 can_run_on_javascript: reader.get_can_run_on_javascript(),
634 }
635 }
636
637 fn record(
638 &self,
639 reader: &value_constructor_variant::record::Reader<'_>,
640 ) -> Result<ValueConstructorVariant> {
641 Ok(ValueConstructorVariant::Record {
642 name: self.string(reader.get_name()?)?,
643 module: self.string(reader.get_module()?)?,
644 arity: reader.get_arity(),
645 variants_count: reader.get_constructors_count(),
646 field_map: self.field_map(&reader.get_field_map()?)?,
647 location: self.src_span(&reader.get_location()?)?,
648 documentation: self.optional_string(self.str(reader.get_documentation()?)?),
649 variant_index: reader.get_constructor_index(),
650 })
651 }
652
653 fn field_map(&self, reader: &option::Reader<'_, field_map::Owned>) -> Result<Option<FieldMap>> {
654 use option::Which;
655 Ok(match reader.which()? {
656 Which::None(_) => None,
657 Which::Some(reader) => Some({
658 let reader = reader?;
659 FieldMap {
660 arity: reader.get_arity(),
661 fields: read_hashmap!(&reader.get_fields()?, self, u32),
662 }
663 }),
664 })
665 }
666
667 fn u32(&self, i: &boxed_u_int32::Reader<'_>) -> Result<u32> {
668 Ok(i.get_value())
669 }
670
671 fn accessors_map(&mut self, reader: &accessors_map::Reader<'_>) -> Result<AccessorsMap> {
672 Ok(AccessorsMap {
673 publicity: self.publicity(reader.get_publicity()?)?,
674 type_: self.type_(&reader.get_type()?)?,
675 shared_accessors: read_hashmap!(&reader.get_shared_accessors()?, self, record_accessor),
676 variant_specific_accessors: read_vec!(
677 &reader.get_variant_specific_accessors()?,
678 self,
679 variant_specific_accessors
680 ),
681 })
682 }
683
684 fn variant_specific_accessors(
685 &mut self,
686 reader: &variant_specific_accessors::Reader<'_>,
687 ) -> Result<HashMap<EcoString, RecordAccessor>> {
688 Ok(read_hashmap!(
689 &reader.get_accessors()?,
690 self,
691 record_accessor
692 ))
693 }
694
695 fn record_accessor(&mut self, reader: &record_accessor::Reader<'_>) -> Result<RecordAccessor> {
696 Ok(RecordAccessor {
697 index: reader.get_index() as u64,
698 label: self.string(reader.get_label()?)?,
699 type_: self.type_(&reader.get_type()?)?,
700 })
701 }
702
703 fn line_starts(&mut self, i: &u32) -> Result<u32> {
704 Ok(*i)
705 }
706
707 fn line_numbers(&mut self, reader: &line_numbers::Reader<'_>) -> Result<LineNumbers> {
708 Ok(LineNumbers {
709 length: reader.get_length(),
710 line_starts: read_vec!(reader.get_line_starts()?, self, line_starts),
711 mapping: self.mapping(reader.get_mapping()?),
712 })
713 }
714
715 fn mapping(
716 &self,
717 reader: capnp::struct_list::Reader<'_, character::Owned>,
718 ) -> HashMap<usize, Character> {
719 let mut map = HashMap::with_capacity(reader.len() as usize);
720 for character in reader.into_iter() {
721 let byte_index = character.get_byte_index() as usize;
722 let length_utf8 = character.get_length_utf8();
723 let length_utf16 = character.get_length_utf16();
724 _ = map.insert(
725 byte_index,
726 Character {
727 length_utf16,
728 length_utf8,
729 },
730 )
731 }
732 map
733 }
734
735 fn version(&self, reader: &version::Reader<'_>) -> hexpm::version::Version {
736 hexpm::version::Version::new(reader.get_major(), reader.get_minor(), reader.get_patch())
737 }
738
739 fn optional_external(
740 &self,
741 reader: option::Reader<'_, external::Owned>,
742 ) -> Result<Option<(EcoString, EcoString)>> {
743 match reader.which()? {
744 option::Which::None(()) => Ok(None),
745 option::Which::Some(reader) => {
746 let reader = reader?;
747 let module = self.string(reader.get_module()?)?;
748 let function = self.string(reader.get_function()?)?;
749 Ok(Some((module, function)))
750 }
751 }
752 }
753}