Skip to main content

solverforge_solver/descriptor/bindings/
lookup.rs

1use solverforge_core::domain::SolutionDescriptor;
2
3use super::variable::VariableBinding;
4
5pub(crate) fn collect_bindings(descriptor: &SolutionDescriptor) -> Vec<VariableBinding> {
6    let mut bindings = Vec::new();
7    for (descriptor_index, entity_descriptor) in descriptor.entity_descriptors.iter().enumerate() {
8        let mut variable_index = 0usize;
9        for variable in entity_descriptor.genuine_variable_descriptors() {
10            let Some(getter) = variable.usize_getter else {
11                continue;
12            };
13            let Some(setter) = variable.usize_setter else {
14                continue;
15            };
16            bindings.push(VariableBinding {
17                binding_index: bindings.len(),
18                descriptor_index,
19                variable_index,
20                entity_type_name: entity_descriptor.type_name,
21                variable_name: variable.name,
22                allows_unassigned: variable.allows_unassigned,
23                getter,
24                setter,
25                value_range_provider: variable.value_range_provider,
26                provider: variable.entity_value_provider,
27                candidate_values: variable.candidate_values,
28                nearby_value_candidates: variable.nearby_value_candidates,
29                nearby_entity_candidates: variable.nearby_entity_candidates,
30                range_type: variable.value_range_type.clone(),
31                nearby_value_distance_meter: variable.nearby_value_distance_meter,
32                nearby_entity_distance_meter: variable.nearby_entity_distance_meter,
33            });
34            variable_index += 1;
35        }
36    }
37    bindings
38}
39
40pub(crate) fn find_binding(
41    bindings: &[VariableBinding],
42    entity_class: Option<&str>,
43    variable_name: Option<&str>,
44) -> Vec<VariableBinding> {
45    bindings
46        .iter()
47        .filter(|binding| entity_class.is_none_or(|name| name == binding.entity_type_name))
48        .filter(|binding| variable_name.is_none_or(|name| name == binding.variable_name))
49        .cloned()
50        .collect()
51}
52
53pub fn descriptor_has_bindings(descriptor: &SolutionDescriptor) -> bool {
54    !collect_bindings(descriptor).is_empty()
55}