Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

gleam / compiler-core / src / metadata / module_decoder.rs
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}