⭐️ A friendly language for building type-safe, scalable systems!
at main 753 lines 28 kB view raw
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}