|
1 | | -use crate::{types::SubtypeChecker, CompositionGraph, PackageId}; |
| 1 | +use crate::{ |
| 2 | + types::{are_semver_compatible, SubtypeChecker}, |
| 3 | + CompositionGraph, PackageId, |
| 4 | +}; |
2 | 5 | use thiserror::Error; |
3 | 6 |
|
4 | 7 | /// Represents an error that can occur when plugging components together. |
@@ -28,31 +31,46 @@ pub fn plug( |
28 | 31 | let socket_instantiation = graph.instantiate(socket); |
29 | 32 |
|
30 | 33 | for plug in plugs { |
31 | | - let mut plug_exports = Vec::new(); |
| 34 | + // Collect matching (plug_export_name, socket_import_name) pairs. |
| 35 | + // The names may differ when matched via semver compatibility. |
| 36 | + let mut plug_exports: Vec<(String, String)> = Vec::new(); |
32 | 37 | let mut cache = Default::default(); |
33 | 38 | let mut checker = SubtypeChecker::new(&mut cache); |
34 | 39 | for (name, plug_ty) in &graph.types()[graph[plug].ty()].exports { |
35 | | - if let Some(socket_ty) = graph.types()[graph[socket].ty()].imports.get(name) { |
| 40 | + // Try exact name match first, then fall back to semver-compatible match |
| 41 | + let matching_import = graph.types()[graph[socket].ty()] |
| 42 | + .imports |
| 43 | + .get(name) |
| 44 | + .map(|ty| (name.clone(), ty)) |
| 45 | + .or_else(|| { |
| 46 | + graph.types()[graph[socket].ty()] |
| 47 | + .imports |
| 48 | + .iter() |
| 49 | + .find(|(import_name, _)| are_semver_compatible(name, import_name)) |
| 50 | + .map(|(import_name, ty)| (import_name.clone(), ty)) |
| 51 | + }); |
| 52 | + |
| 53 | + if let Some((socket_name, socket_ty)) = matching_import { |
36 | 54 | if checker |
37 | 55 | .is_subtype(*plug_ty, graph.types(), *socket_ty, graph.types()) |
38 | 56 | .is_ok() |
39 | 57 | { |
40 | | - plug_exports.push(name.clone()); |
| 58 | + plug_exports.push((name.clone(), socket_name)); |
41 | 59 | } |
42 | 60 | } |
43 | 61 | } |
44 | 62 |
|
45 | 63 | // Instantiate the plug component |
46 | 64 | let mut plug_instantiation = None; |
47 | | - for plug_name in plug_exports { |
| 65 | + for (plug_name, socket_name) in plug_exports { |
48 | 66 | log::debug!("using export `{plug_name}` for plug"); |
49 | 67 | let plug_instantiation = |
50 | 68 | *plug_instantiation.get_or_insert_with(|| graph.instantiate(plug)); |
51 | 69 | let export = graph |
52 | 70 | .alias_instance_export(plug_instantiation, &plug_name) |
53 | 71 | .map_err(|err| PlugError::GraphError { source: err.into() })?; |
54 | 72 | graph |
55 | | - .set_instantiation_argument(socket_instantiation, &plug_name, export) |
| 73 | + .set_instantiation_argument(socket_instantiation, &socket_name, export) |
56 | 74 | .map_err(|err| PlugError::GraphError { source: err.into() })?; |
57 | 75 | } |
58 | 76 | } |
|
0 commit comments