Skip to content

Conversation

@rescrv
Copy link
Contributor

@rescrv rescrv commented Dec 26, 2025

Description of changes

This PR introduces the types for multi-region, multi-cloud support.

Test plan

CI

Migration plan

Not applicable yet.

Observability plan

N/A

Documentation Changes

N/A

@github-actions
Copy link

Reviewer Checklist

Please leverage this checklist to ensure your code review is thorough before approving

Testing, Bugs, Errors, Logs, Documentation

  • Can you think of any use case in which the code does not behave as intended? Have they been tested?
  • Can you think of any inputs or external events that could break the code? Is user input validated and safe? Have they been tested?
  • If appropriate, are there adequate property based tests?
  • If appropriate, are there adequate unit tests?
  • Should any logging, debugging, tracing information be added or removed?
  • Are error messages user-friendly?
  • Have all documentation changes needed been made?
  • Have all non-obvious changes been commented?

System Compatibility

  • Are there any potential impacts on other parts of the system or backward compatibility?
  • Does this change intersect with any items on our roadmap, and if so, is there a plan for fitting them together?

Quality

  • Is this code of a unexpectedly high quality (Readability, Modularity, Intuitiveness)

@propel-code-bot
Copy link
Contributor

propel-code-bot bot commented Dec 26, 2025

Introduce multi-cloud topology configuration types

Adds a new rust/types/src/topology.rs module that defines strongly typed primitives for regions, topologies, and full multi-region configurations along with validation and serde support. Updates rust/types/src/lib.rs to expose the module so downstream crates can construct and validate multi-cloud topology declarations.

Key Changes

• Introduced RegionName, TopologyName, ProviderRegion<T>, Topology, and MultiCloudMultiRegionConfiguration<T> types with serde serialization/deserialization and display helpers in rust/types/src/topology.rs.
• Implemented validation logic (including duplicate detection and unknown reference checks) returning rich ValidationError diagnostics, plus a reusable find_duplicates helper.
• Added extensive unit tests covering constructors, accessors, serde round-trips, and validation error scenarios for the new types.
• Re-exported the new topology module through rust/types/src/lib.rs.

Affected Areas

• rust/types/src/topology.rs
• rust/types/src/lib.rs

This summary was automatically generated by @propel-code-bot

serialize = "T: Clone + Debug + Eq + PartialEq + Serialize",
deserialize = "T: Clone + Debug + Eq + PartialEq + serde::de::DeserializeOwned"
))]
pub struct ProviderRegion<T: Clone + Debug + Eq + PartialEq + Serialize + for<'a> Deserialize<'a>> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommended

[Maintainability] For consistency and clarity, consider using serde::de::DeserializeOwned as the trait bound for T instead of for<'a> Deserialize<'a>. The manual Deserialize implementation for MultiCloudMultiRegionConfiguration already uses DeserializeOwned, and since T represents owned configuration data, this bound is more idiomatic.

This change would also apply to the MultiCloudMultiRegionConfiguration struct definition and associated impl blocks.

Context for Agents
For consistency and clarity, consider using `serde::de::DeserializeOwned` as the trait bound for `T` instead of `for<'a> Deserialize<'a>`. The manual `Deserialize` implementation for `MultiCloudMultiRegionConfiguration` already uses `DeserializeOwned`, and since `T` represents owned configuration data, this bound is more idiomatic.

This change would also apply to the `MultiCloudMultiRegionConfiguration` struct definition and associated `impl` blocks.

File: rust/types/src/topology.rs
Line: 177

Comment on lines +458 to +498
fn format_message(&self) -> String {
if !self.has_errors() {
return "no validation errors".to_string();
}

let mut parts = Vec::new();

if !self.duplicate_region_names.is_empty() {
let names: Vec<&str> = self
.duplicate_region_names
.iter()
.map(|n| n.as_str())
.collect();
parts.push(format!("duplicate region names: {}", names.join(", ")));
}

if !self.duplicate_topology_names.is_empty() {
let names: Vec<&str> = self
.duplicate_topology_names
.iter()
.map(|n| n.as_str())
.collect();
parts.push(format!("duplicate topology names: {}", names.join(", ")));
}

if !self.unknown_topology_regions.is_empty() {
let names: Vec<&str> = self
.unknown_topology_regions
.iter()
.map(|n| n.as_str())
.collect();
parts.push(format!("unknown topology regions: {}", names.join(", ")));
}

if let Some(ref name) = self.unknown_preferred_region {
parts.push(format!("unknown preferred region: {}", name.as_str()));
}

parts.join("; ")
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommended

[Maintainability] The format_message function contains repetitive logic for formatting lists of names. This can be extracted into a private helper function to improve code clarity and maintainability by following the DRY (Don't Repeat Yourself) principle. This also provides an opportunity to use the Display implementation directly instead of as_str().

Context for Agents
The `format_message` function contains repetitive logic for formatting lists of names. This can be extracted into a private helper function to improve code clarity and maintainability by following the DRY (Don't Repeat Yourself) principle. This also provides an opportunity to use the `Display` implementation directly instead of `as_str()`.

File: rust/types/src/topology.rs
Line: 498

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants