⭐️ A friendly language for building type-safe, scalable systems!
at main 728 lines 29 kB view raw
1use ecow::EcoString; 2 3use crate::{ 4 ast::{ 5 Constant, Publicity, SrcSpan, TypedConstant, TypedConstantBitArraySegment, 6 TypedConstantBitArraySegmentOption, 7 }, 8 reference::{Reference, ReferenceKind, ReferenceMap}, 9 schema_capnp::{self as schema, *}, 10 type_::{ 11 self, AccessorsMap, Deprecation, FieldMap, Opaque, RecordAccessor, Type, 12 TypeAliasConstructor, TypeConstructor, TypeValueConstructor, TypeVar, 13 TypeVariantConstructors, ValueConstructor, ValueConstructorVariant, 14 expression::{Implementations, Purity}, 15 }, 16}; 17use std::{collections::HashMap, ops::Deref, sync::Arc}; 18 19#[derive(Debug)] 20pub struct ModuleEncoder<'a> { 21 data: &'a type_::ModuleInterface, 22 next_type_var_id: u64, 23 type_var_id_map: HashMap<u64, u64>, 24} 25 26impl<'a> ModuleEncoder<'a> { 27 pub fn new(data: &'a type_::ModuleInterface) -> Self { 28 Self { 29 data, 30 next_type_var_id: 0, 31 type_var_id_map: HashMap::new(), 32 } 33 } 34 35 pub fn encode(mut self) -> crate::Result<Vec<u8>> { 36 let span = tracing::info_span!("metadata"); 37 let _enter = span.enter(); 38 let mut buffer = Vec::new(); 39 40 let mut message = capnp::message::Builder::new_default(); 41 42 let mut module = message.init_root::<module::Builder<'_>>(); 43 module.set_name(&self.data.name); 44 module.set_package(&self.data.package); 45 module.set_src_path(self.data.src_path.as_str()); 46 module.set_is_internal(self.data.is_internal); 47 module.set_contains_echo(self.data.contains_echo); 48 self.set_module_types(&mut module); 49 self.set_module_values(&mut module); 50 self.set_module_accessors(&mut module); 51 self.set_module_types_constructors(&mut module); 52 self.set_line_numbers(&mut module); 53 self.set_version(&mut module); 54 self.set_module_documentation(&mut module); 55 self.set_module_type_aliases(&mut module); 56 self.set_module_references(&mut module); 57 58 capnp::serialize_packed::write_message(&mut buffer, &message).expect("capnp encode"); 59 Ok(buffer) 60 } 61 62 fn set_line_numbers(&mut self, module: &mut module::Builder<'_>) { 63 let mut line_numbers = module.reborrow().init_line_numbers(); 64 line_numbers.set_length(self.data.line_numbers.length); 65 66 let mut line_starts = line_numbers 67 .reborrow() 68 .init_line_starts(self.data.line_numbers.line_starts.len() as u32); 69 for (i, l) in self.data.line_numbers.line_starts.iter().enumerate() { 70 line_starts.reborrow().set(i as u32, *l); 71 } 72 73 let mut mapping = line_numbers.init_mapping(self.data.line_numbers.mapping.len() as u32); 74 for (i, (byte_index, character)) in self.data.line_numbers.mapping.iter().enumerate() { 75 let mut builder = mapping.reborrow().get(i as u32); 76 builder.set_byte_index(*byte_index as u64); 77 builder.set_length_utf8(character.length_utf8); 78 builder.set_length_utf16(character.length_utf16); 79 } 80 } 81 82 fn set_module_documentation(&mut self, module: &mut module::Builder<'_>) { 83 let mut documentation = module 84 .reborrow() 85 .init_documentation(self.data.documentation.len() as u32); 86 for (i, documentation_part) in self.data.documentation.iter().enumerate() { 87 documentation.set(i as u32, documentation_part.as_str()); 88 } 89 } 90 91 fn set_module_accessors(&mut self, module: &mut module::Builder<'_>) { 92 let mut builder = module 93 .reborrow() 94 .init_accessors(self.data.accessors.len() as u32); 95 for (i, (key, map)) in self.data.accessors.iter().enumerate() { 96 let mut property = builder.reborrow().get(i as u32); 97 property.set_key(key); 98 self.build_accessors_map(property.init_value(), map); 99 } 100 } 101 102 fn build_accessors_map( 103 &mut self, 104 mut builder: accessors_map::Builder<'_>, 105 accessors: &AccessorsMap, 106 ) { 107 self.build_type(builder.reborrow().init_type(), &accessors.type_); 108 self.build_publicity(builder.reborrow().init_publicity(), accessors.publicity); 109 let mut accessors_builder = builder 110 .reborrow() 111 .init_shared_accessors(accessors.shared_accessors.len() as u32); 112 for (i, (name, accessor)) in accessors.shared_accessors.iter().enumerate() { 113 let mut property = accessors_builder.reborrow().get(i as u32); 114 property.set_key(name); 115 self.build_record_accessor(property.init_value(), accessor) 116 } 117 118 let mut builder = builder 119 .init_variant_specific_accessors(accessors.variant_specific_accessors.len() as u32); 120 for (i, map) in accessors.variant_specific_accessors.iter().enumerate() { 121 self.build_constructor_accessors(builder.reborrow().get(i as u32), map); 122 } 123 } 124 125 fn build_constructor_accessors( 126 &mut self, 127 builder: variant_specific_accessors::Builder<'_>, 128 accessors: &HashMap<EcoString, RecordAccessor>, 129 ) { 130 let mut builder = builder.init_accessors(accessors.len() as u32); 131 for (i, (name, accessor)) in accessors.iter().enumerate() { 132 let mut property = builder.reborrow().get(i as u32); 133 property.set_key(name); 134 self.build_record_accessor(property.init_value(), accessor) 135 } 136 } 137 138 fn build_record_accessor( 139 &mut self, 140 mut builder: record_accessor::Builder<'_>, 141 accessor: &RecordAccessor, 142 ) { 143 self.build_type(builder.reborrow().init_type(), &accessor.type_); 144 builder.reborrow().set_label(&accessor.label); 145 builder.set_index(accessor.index as u16); 146 } 147 148 fn set_module_types(&mut self, module: &mut module::Builder<'_>) { 149 let mut types = module.reborrow().init_types(self.data.types.len() as u32); 150 for (i, (name, type_)) in self.data.types.iter().enumerate() { 151 let mut property = types.reborrow().get(i as u32); 152 property.set_key(name); 153 self.build_type_constructor(property.init_value(), type_) 154 } 155 } 156 157 fn set_module_type_aliases(&mut self, module: &mut module::Builder<'_>) { 158 let mut types = module 159 .reborrow() 160 .init_type_aliases(self.data.type_aliases.len() as u32); 161 for (i, (name, alias)) in self.data.type_aliases.iter().enumerate() { 162 let mut property = types.reborrow().get(i as u32); 163 property.set_key(name); 164 self.build_type_alias_constructor(property.init_value(), alias) 165 } 166 } 167 168 fn set_module_types_constructors(&mut self, module: &mut module::Builder<'_>) { 169 let mut types_constructors = module 170 .reborrow() 171 .init_types_constructors(self.data.types_value_constructors.len() as u32); 172 for (i, (name, data)) in self.data.types_value_constructors.iter().enumerate() { 173 let mut property = types_constructors.reborrow().get(i as u32); 174 property.set_key(name); 175 self.build_type_variant_constructors(property.init_value(), data) 176 } 177 } 178 179 fn build_type_variant_constructors( 180 &mut self, 181 mut builder: types_variant_constructors::Builder<'_>, 182 data: &TypeVariantConstructors, 183 ) { 184 match data.opaque { 185 Opaque::Opaque => builder.set_opaque(true), 186 Opaque::NotOpaque => builder.set_opaque(false), 187 } 188 { 189 let mut builder = builder 190 .reborrow() 191 .init_type_parameters_ids(data.type_parameters_ids.len() as u32); 192 for (i, id) in data.type_parameters_ids.iter().enumerate() { 193 let id = self.get_or_insert_type_var_id(*id); 194 builder.set(i as u32, id as u16); 195 } 196 } 197 let mut builder = builder.init_variants(data.variants.len() as u32); 198 for (i, constructor) in data.variants.iter().enumerate() { 199 self.build_type_value_constructor(builder.reborrow().get(i as u32), constructor); 200 } 201 } 202 203 fn set_module_values(&mut self, module: &mut module::Builder<'_>) { 204 let mut values = module.reborrow().init_values(self.data.values.len() as u32); 205 for (i, (name, value)) in self.data.values.iter().enumerate() { 206 let mut property = values.reborrow().get(i as u32); 207 property.set_key(name); 208 self.build_value_constructor(property.init_value(), value) 209 } 210 } 211 212 fn set_module_references(&mut self, module: &mut module::Builder<'_>) { 213 let references = &self.data.references; 214 let mut builder = module.reborrow().init_references(); 215 let mut imported_modules = builder 216 .reborrow() 217 .init_imported_modules(references.imported_modules.len() as u32); 218 for (i, module) in references.imported_modules.iter().enumerate() { 219 imported_modules.set(i as u32, module); 220 } 221 222 let value_references = builder 223 .reborrow() 224 .init_value_references(references.value_references.len() as u32); 225 self.build_reference_map(value_references, &references.value_references); 226 let type_references = builder 227 .reborrow() 228 .init_type_references(references.type_references.len() as u32); 229 self.build_reference_map(type_references, &references.type_references); 230 } 231 232 fn build_reference_map( 233 &mut self, 234 mut builder: capnp::struct_list::Builder<'_, reference_map::Owned>, 235 map: &ReferenceMap, 236 ) { 237 for (i, ((module, name), references)) in map.iter().enumerate() { 238 let mut builder = builder.reborrow().get(i as u32); 239 builder.set_module(module); 240 builder.set_name(name); 241 let mut references_builder = 242 builder.reborrow().init_references(references.len() as u32); 243 for (i, reference) in references.iter().enumerate() { 244 let builder = references_builder.reborrow().get(i as u32); 245 self.build_reference(builder, reference); 246 } 247 } 248 } 249 250 fn build_reference(&mut self, mut builder: reference::Builder<'_>, reference: &Reference) { 251 let mut kind = builder.reborrow().init_kind(); 252 match reference.kind { 253 ReferenceKind::Qualified => kind.set_qualified(()), 254 ReferenceKind::Unqualified => kind.set_unqualified(()), 255 ReferenceKind::Import => kind.set_import(()), 256 ReferenceKind::Definition => kind.set_definition(()), 257 ReferenceKind::Alias => kind.set_alias(()), 258 } 259 self.build_src_span(builder.init_location(), reference.location); 260 } 261 262 fn set_version(&mut self, module: &mut module::Builder<'_>) { 263 let mut version = module.reborrow().init_required_version(); 264 version.set_major(self.data.minimum_required_version.major); 265 version.set_minor(self.data.minimum_required_version.minor); 266 version.set_patch(self.data.minimum_required_version.patch); 267 } 268 269 fn build_type_constructor( 270 &mut self, 271 mut builder: type_constructor::Builder<'_>, 272 constructor: &TypeConstructor, 273 ) { 274 builder.set_module(&constructor.module); 275 builder.set_deprecated(match &constructor.deprecation { 276 Deprecation::NotDeprecated => "", 277 Deprecation::Deprecated { message } => message, 278 }); 279 self.build_publicity(builder.reborrow().init_publicity(), constructor.publicity); 280 let type_builder = builder.reborrow().init_type(); 281 self.build_type(type_builder, &constructor.type_); 282 self.build_types( 283 builder 284 .reborrow() 285 .init_parameters(constructor.parameters.len() as u32), 286 &constructor.parameters, 287 ); 288 self.build_src_span(builder.reborrow().init_origin(), constructor.origin); 289 builder.set_documentation( 290 constructor 291 .documentation 292 .as_ref() 293 .map(EcoString::as_str) 294 .unwrap_or_default(), 295 ); 296 } 297 298 fn build_type_alias_constructor( 299 &mut self, 300 mut builder: type_alias_constructor::Builder<'_>, 301 constructor: &TypeAliasConstructor, 302 ) { 303 builder.set_module(&constructor.module); 304 builder.set_deprecation(match &constructor.deprecation { 305 Deprecation::NotDeprecated => "", 306 Deprecation::Deprecated { message } => message, 307 }); 308 self.build_publicity(builder.reborrow().init_publicity(), constructor.publicity); 309 let type_builder = builder.reborrow().init_type(); 310 self.build_type(type_builder, &constructor.type_); 311 self.build_src_span(builder.reborrow().init_origin(), constructor.origin); 312 builder.set_documentation(constructor.documentation.as_deref().unwrap_or_default()); 313 builder.set_arity(constructor.arity as u32) 314 } 315 316 fn build_type_value_constructor( 317 &mut self, 318 mut builder: type_value_constructor::Builder<'_>, 319 constructor: &TypeValueConstructor, 320 ) { 321 builder.set_name(&constructor.name); 322 builder.set_documentation(constructor.documentation.as_deref().unwrap_or_default()); 323 let mut builder = builder.init_parameters(constructor.parameters.len() as u32); 324 for (i, parameter) in constructor.parameters.iter().enumerate() { 325 self.build_type_value_constructor_parameter( 326 builder.reborrow().get(i as u32), 327 parameter, 328 ); 329 } 330 } 331 332 fn build_type_value_constructor_parameter( 333 &mut self, 334 mut builder: type_value_constructor_parameter::Builder<'_>, 335 parameter: &type_::TypeValueConstructorField, 336 ) { 337 self.build_type(builder.reborrow().init_type(), parameter.type_.as_ref()); 338 builder.set_label(parameter.label.as_deref().unwrap_or_default()); 339 } 340 341 fn build_value_constructor( 342 &mut self, 343 mut builder: value_constructor::Builder<'_>, 344 constructor: &ValueConstructor, 345 ) { 346 builder.set_deprecated(match &constructor.deprecation { 347 Deprecation::NotDeprecated => "", 348 Deprecation::Deprecated { message } => message, 349 }); 350 351 self.build_publicity(builder.reborrow().init_publicity(), constructor.publicity); 352 self.build_type(builder.reborrow().init_type(), &constructor.type_); 353 self.build_value_constructor_variant(builder.init_variant(), &constructor.variant); 354 } 355 356 fn build_publicity(&mut self, mut builder: publicity::Builder<'_>, publicity: Publicity) { 357 match publicity { 358 Publicity::Public => builder.set_public(()), 359 Publicity::Private => builder.set_private(()), 360 Publicity::Internal { 361 attribute_location: None, 362 } => { 363 let mut builder = builder.init_internal(); 364 builder.set_none(()); 365 } 366 Publicity::Internal { 367 attribute_location: Some(location), 368 } => { 369 let builder = builder.init_internal(); 370 let builder = builder.init_some(); 371 self.build_src_span(builder, location); 372 } 373 } 374 } 375 376 fn build_src_span(&mut self, mut builder: src_span::Builder<'_>, span: SrcSpan) { 377 builder.set_start(span.start); 378 builder.set_end(span.end); 379 } 380 381 fn build_value_constructor_variant( 382 &mut self, 383 builder: value_constructor_variant::Builder<'_>, 384 constructor: &ValueConstructorVariant, 385 ) { 386 match constructor { 387 ValueConstructorVariant::LocalVariable { .. } => { 388 panic!("Unexpected local variable value constructor in module interface",) 389 } 390 391 ValueConstructorVariant::LocalConstant { .. } => { 392 panic!("Unexpected local constant value constructor in module interface",) 393 } 394 395 ValueConstructorVariant::ModuleConstant { 396 literal, 397 location, 398 module, 399 documentation: doc, 400 implementations, 401 name, 402 } => { 403 let mut builder = builder.init_module_constant(); 404 builder.set_documentation(doc.as_ref().map(EcoString::as_str).unwrap_or_default()); 405 self.build_src_span(builder.reborrow().init_location(), *location); 406 self.build_constant(builder.reborrow().init_literal(), literal); 407 builder.reborrow().set_module(module); 408 builder.reborrow().set_name(name); 409 self.build_implementations(builder.init_implementations(), *implementations) 410 } 411 412 ValueConstructorVariant::Record { 413 name, 414 field_map, 415 arity, 416 location, 417 module, 418 variants_count: constructors_count, 419 variant_index: constructor_index, 420 documentation: doc, 421 } => { 422 let mut builder = builder.init_record(); 423 builder.set_name(name); 424 builder.set_module(module); 425 builder.set_arity(*arity); 426 builder.set_documentation(doc.as_ref().map(EcoString::as_str).unwrap_or_default()); 427 builder.set_constructors_count(*constructors_count); 428 builder.set_constructor_index(*constructor_index); 429 self.build_optional_field_map(builder.reborrow().init_field_map(), field_map); 430 self.build_src_span(builder.init_location(), *location); 431 } 432 433 ValueConstructorVariant::ModuleFn { 434 arity, 435 field_map, 436 module, 437 name, 438 location, 439 documentation: doc, 440 implementations, 441 external_erlang, 442 external_javascript, 443 purity, 444 } => { 445 let mut builder = builder.init_module_fn(); 446 builder.set_name(name); 447 builder.set_module(module); 448 builder.set_arity(*arity as u16); 449 builder.set_documentation(doc.as_ref().map(EcoString::as_str).unwrap_or_default()); 450 451 let mut purity_builder = builder.reborrow().init_purity(); 452 match purity { 453 Purity::Pure => purity_builder.set_pure(()), 454 Purity::TrustedPure => purity_builder.set_trusted_pure(()), 455 Purity::Impure => purity_builder.set_impure(()), 456 Purity::Unknown => purity_builder.set_unknown(()), 457 } 458 459 self.build_external(builder.reborrow().init_external_erlang(), external_erlang); 460 self.build_external( 461 builder.reborrow().init_external_javascript(), 462 external_javascript, 463 ); 464 self.build_optional_field_map(builder.reborrow().init_field_map(), field_map); 465 self.build_src_span(builder.reborrow().init_location(), *location); 466 self.build_implementations(builder.init_implementations(), *implementations); 467 } 468 } 469 } 470 471 fn build_optional_field_map( 472 &mut self, 473 mut builder: option::Builder<'_, field_map::Owned>, 474 field_map: &Option<FieldMap>, 475 ) { 476 match field_map { 477 Some(field_map) => self.build_field_map(builder.init_some(), field_map), 478 None => builder.set_none(()), 479 }; 480 } 481 482 fn build_field_map(&mut self, mut builder: field_map::Builder<'_>, field_map: &FieldMap) { 483 builder.set_arity(field_map.arity); 484 let mut builder = builder.init_fields(field_map.fields.len() as u32); 485 for (i, (name, &position)) in field_map.fields.iter().enumerate() { 486 let mut field = builder.reborrow().get(i as u32); 487 field.set_key(name); 488 field.init_value().set_value(position); 489 } 490 } 491 492 fn build_constant(&mut self, mut builder: constant::Builder<'_>, constant: &TypedConstant) { 493 match constant { 494 Constant::Int { value, .. } => builder.set_int(value), 495 Constant::Float { value, .. } => builder.set_float(value), 496 Constant::String { value, .. } => builder.set_string(value), 497 498 Constant::Tuple { elements, .. } => { 499 self.build_constants(builder.init_tuple(elements.len() as u32), elements) 500 } 501 502 Constant::List { 503 elements, type_, .. 504 } => { 505 let mut builder = builder.init_list(); 506 self.build_constants( 507 builder.reborrow().init_elements(elements.len() as u32), 508 elements, 509 ); 510 self.build_type(builder.init_type(), type_); 511 } 512 513 Constant::BitArray { segments, .. } => { 514 let mut builder = builder.init_bit_array(segments.len() as u32); 515 for (i, segment) in segments.iter().enumerate() { 516 self.build_bit_array_segment(builder.reborrow().get(i as u32), segment); 517 } 518 } 519 520 Constant::Record { 521 args, tag, type_, .. 522 } => { 523 let mut builder = builder.init_record(); 524 { 525 let mut builder = builder.reborrow().init_args(args.len() as u32); 526 for (i, arg) in args.iter().enumerate() { 527 self.build_constant(builder.reborrow().get(i as u32), &arg.value); 528 } 529 } 530 builder.reborrow().set_tag(tag); 531 self.build_type(builder.reborrow().init_type(), type_); 532 } 533 534 Constant::Var { 535 module, 536 name, 537 type_, 538 constructor, 539 .. 540 } => { 541 let mut builder = builder.init_var(); 542 match module { 543 Some((name, _)) => builder.set_module(name), 544 None => builder.set_module(""), 545 }; 546 builder.set_name(name); 547 self.build_type(builder.reborrow().init_type(), type_); 548 self.build_value_constructor( 549 builder.reborrow().init_constructor(), 550 constructor 551 .as_ref() 552 .expect("This is guaranteed to hold a value."), 553 ); 554 } 555 556 Constant::StringConcatenation { right, left, .. } => { 557 let mut builder = builder.init_string_concatenation(); 558 self.build_constant(builder.reborrow().init_right(), right); 559 self.build_constant(builder.reborrow().init_left(), left); 560 } 561 562 Constant::Invalid { .. } => { 563 panic!("invalid constants should not reach code generation") 564 } 565 } 566 } 567 568 fn build_constants( 569 &mut self, 570 mut builder: capnp::struct_list::Builder<'_, constant::Owned>, 571 constant: &[TypedConstant], 572 ) { 573 for (i, constant) in constant.iter().enumerate() { 574 self.build_constant(builder.reborrow().get(i as u32), constant); 575 } 576 } 577 578 fn build_bit_array_segment( 579 &mut self, 580 mut builder: bit_array_segment::Builder<'_>, 581 segment: &TypedConstantBitArraySegment, 582 ) { 583 self.build_constant(builder.reborrow().init_value(), &segment.value); 584 { 585 let mut builder = builder 586 .reborrow() 587 .init_options(segment.options.len() as u32); 588 for (i, option) in segment.options.iter().enumerate() { 589 self.build_bit_array_segment_option(builder.reborrow().get(i as u32), option); 590 } 591 } 592 self.build_type(builder.init_type(), &segment.type_); 593 } 594 595 fn build_bit_array_segment_option( 596 &mut self, 597 mut builder: bit_array_segment_option::Builder<'_>, 598 option: &TypedConstantBitArraySegmentOption, 599 ) { 600 use crate::ast::TypedConstantBitArraySegmentOption as Opt; 601 match option { 602 Opt::Bytes { .. } => builder.set_bytes(()), 603 Opt::Int { .. } => builder.set_integer(()), 604 Opt::Float { .. } => builder.set_float(()), 605 Opt::Bits { .. } => builder.set_bits(()), 606 Opt::Utf8 { .. } => builder.set_utf8(()), 607 Opt::Utf16 { .. } => builder.set_utf16(()), 608 Opt::Utf32 { .. } => builder.set_utf32(()), 609 Opt::Utf8Codepoint { .. } => builder.set_utf8_codepoint(()), 610 Opt::Utf16Codepoint { .. } => builder.set_utf16_codepoint(()), 611 Opt::Utf32Codepoint { .. } => builder.set_utf32_codepoint(()), 612 Opt::Signed { .. } => builder.set_signed(()), 613 Opt::Unsigned { .. } => builder.set_unsigned(()), 614 Opt::Big { .. } => builder.set_big(()), 615 Opt::Little { .. } => builder.set_little(()), 616 Opt::Native { .. } => builder.set_native(()), 617 618 Opt::Size { 619 value, short_form, .. 620 } => { 621 let mut builder = builder.init_size(); 622 self.build_constant(builder.reborrow().init_value(), value); 623 builder.set_short_form(*short_form); 624 } 625 626 Opt::Unit { value, .. } => { 627 let mut builder = builder.init_unit(); 628 builder.set_value(*value); 629 } 630 } 631 } 632 633 fn build_type(&mut self, builder: schema::type_::Builder<'_>, type_: &Type) { 634 match type_ { 635 Type::Fn { args, return_ } => { 636 let mut fun = builder.init_fn(); 637 self.build_types(fun.reborrow().init_arguments(args.len() as u32), args); 638 self.build_type(fun.init_return(), return_) 639 } 640 641 Type::Named { 642 name, 643 args, 644 module, 645 package, 646 inferred_variant, 647 .. 648 } => { 649 let mut app = builder.init_app(); 650 app.set_name(name); 651 app.set_module(module); 652 app.set_package(package); 653 let mut variant_builder = app.reborrow().init_inferred_variant(); 654 match inferred_variant { 655 Some(variant) => variant_builder.set_inferred(*variant), 656 None => variant_builder.set_unknown(()), 657 } 658 self.build_types(app.reborrow().init_parameters(args.len() as u32), args); 659 } 660 661 Type::Tuple { elements } => self.build_types( 662 builder.init_tuple().init_elements(elements.len() as u32), 663 elements, 664 ), 665 666 Type::Var { type_ } => match type_.borrow().deref() { 667 TypeVar::Link { type_ } => self.build_type(builder, type_), 668 TypeVar::Unbound { id, .. } | TypeVar::Generic { id } => { 669 self.build_type_var(builder.init_var(), *id) 670 } 671 }, 672 } 673 } 674 675 fn build_types( 676 &mut self, 677 mut builder: capnp::struct_list::Builder<'_, schema::type_::Owned>, 678 types: &[Arc<Type>], 679 ) { 680 for (i, type_) in types.iter().enumerate() { 681 self.build_type(builder.reborrow().get(i as u32), type_); 682 } 683 } 684 685 fn build_type_var(&mut self, mut builder: schema::type_::var::Builder<'_>, id: u64) { 686 let serialised_id = self.get_or_insert_type_var_id(id); 687 builder.set_id(serialised_id); 688 } 689 690 fn get_or_insert_type_var_id(&mut self, id: u64) -> u64 { 691 match self.type_var_id_map.get(&id) { 692 Some(&id) => id, 693 None => { 694 let new_id = self.next_type_var_id; 695 self.next_type_var_id += 1; 696 let _ = self.type_var_id_map.insert(id, new_id); 697 new_id 698 } 699 } 700 } 701 702 fn build_implementations( 703 &self, 704 mut builder: implementations::Builder<'_>, 705 implementations: Implementations, 706 ) { 707 builder.set_gleam(implementations.gleam); 708 builder.set_uses_erlang_externals(implementations.uses_erlang_externals); 709 builder.set_uses_javascript_externals(implementations.uses_javascript_externals); 710 builder.set_can_run_on_erlang(implementations.can_run_on_erlang); 711 builder.set_can_run_on_javascript(implementations.can_run_on_javascript); 712 } 713 714 fn build_external( 715 &self, 716 mut builder: option::Builder<'_, external::Owned>, 717 external: &Option<(EcoString, EcoString)>, 718 ) { 719 match external { 720 None => builder.set_none(()), 721 Some((module, function)) => { 722 let mut builder = builder.init_some(); 723 builder.set_module(module); 724 builder.set_function(function); 725 } 726 } 727 } 728}