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