use std::collections::HashMap;
use crate::{api::RoadPosition, common::MaliputError};
use strum_macros::{Display, IntoStaticStr};
pub struct TrafficLightBook<'a> {
pub(super) traffic_light_book: &'a maliput_sys::api::rules::ffi::TrafficLightBook,
}
impl<'a> TrafficLightBook<'a> {
pub fn traffic_lights(&self) -> Vec<TrafficLight<'_>> {
let traffic_lights_cpp = maliput_sys::api::rules::ffi::TrafficLightBook_TrafficLights(self.traffic_light_book);
traffic_lights_cpp
.into_iter()
.map(|tl| TrafficLight {
traffic_light: unsafe { tl.traffic_light.as_ref().expect("") },
})
.collect::<Vec<TrafficLight>>()
}
pub fn get_traffic_light(&self, id: &String) -> Option<TrafficLight<'_>> {
let traffic_light = maliput_sys::api::rules::ffi::TrafficLightBook_GetTrafficLight(self.traffic_light_book, id);
if traffic_light.is_null() {
return None;
}
Some(TrafficLight {
traffic_light: unsafe {
traffic_light
.as_ref()
.expect("Unable to get underlying traffic light pointer")
},
})
}
pub fn find_by_lane(&self, lane_id: &String) -> Vec<TrafficLight<'_>> {
let traffic_lights_cpp =
maliput_sys::api::rules::ffi::TrafficLightBook_FindByLane(self.traffic_light_book, lane_id);
traffic_lights_cpp
.into_iter()
.map(|tl| TrafficLight {
traffic_light: unsafe { tl.traffic_light.as_ref().expect("TrafficLight pointer is null") },
})
.collect::<Vec<TrafficLight>>()
}
}
pub struct TrafficLight<'a> {
pub traffic_light: &'a maliput_sys::api::rules::ffi::TrafficLight,
}
impl<'a> TrafficLight<'a> {
pub fn id(&self) -> String {
maliput_sys::api::rules::ffi::TrafficLight_id(self.traffic_light)
}
pub fn position_road_network(&self) -> super::InertialPosition {
let inertial_position = maliput_sys::api::rules::ffi::TrafficLight_position_road_network(self.traffic_light);
super::InertialPosition { ip: inertial_position }
}
pub fn orientation_road_network(&self) -> super::Rotation {
let rotation = maliput_sys::api::rules::ffi::TrafficLight_orientation_road_network(self.traffic_light);
super::Rotation { r: rotation }
}
pub fn bulb_groups(&self) -> Vec<BulbGroup<'_>> {
let bulb_groups_cpp = maliput_sys::api::rules::ffi::TrafficLight_bulb_groups(self.traffic_light);
bulb_groups_cpp
.into_iter()
.map(|bg| BulbGroup {
bulb_group: unsafe { bg.bulb_group.as_ref().expect("") },
})
.collect::<Vec<BulbGroup>>()
}
pub fn get_bulb_group(&self, id: &String) -> Option<BulbGroup<'_>> {
let bulb_group = maliput_sys::api::rules::ffi::TrafficLight_GetBulbGroup(self.traffic_light, id);
if bulb_group.is_null() {
return None;
}
Some(BulbGroup {
bulb_group: unsafe {
bulb_group
.as_ref()
.expect("Unable to get underlying bulb group pointer")
},
})
}
pub fn related_lanes(&self) -> Vec<String> {
maliput_sys::api::rules::ffi::TrafficLight_related_lanes(self.traffic_light)
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum BulbColor {
Red,
Yellow,
Green,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum BulbType {
Round,
Arrow,
ArrowLeft,
ArrowRight,
ArrowUp,
ArrowUpperLeft,
ArrowUpperRight,
UTurnLeft,
UTurnRight,
Walk,
DontWalk,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum BulbState {
Off,
On,
Blinking,
}
pub struct Bulb<'a> {
pub bulb: &'a maliput_sys::api::rules::ffi::Bulb,
}
impl Bulb<'_> {
pub fn unique_id(&self) -> UniqueBulbId {
UniqueBulbId {
unique_bulb_id: maliput_sys::api::rules::ffi::Bulb_unique_id(self.bulb),
}
}
pub fn id(&self) -> String {
maliput_sys::api::rules::ffi::Bulb_id(self.bulb)
}
pub fn color(&self) -> BulbColor {
let color = self.bulb.color();
match *color {
maliput_sys::api::rules::ffi::BulbColor::kRed => BulbColor::Red,
maliput_sys::api::rules::ffi::BulbColor::kYellow => BulbColor::Yellow,
maliput_sys::api::rules::ffi::BulbColor::kGreen => BulbColor::Green,
_ => panic!("Invalid bulb color"),
}
}
pub fn bulb_type(&self) -> BulbType {
let bulb_type = maliput_sys::api::rules::ffi::Bulb_type(self.bulb);
match *bulb_type {
maliput_sys::api::rules::ffi::BulbType::kRound => BulbType::Round,
maliput_sys::api::rules::ffi::BulbType::kArrow => BulbType::Arrow,
maliput_sys::api::rules::ffi::BulbType::kArrowLeft => BulbType::ArrowLeft,
maliput_sys::api::rules::ffi::BulbType::kArrowRight => BulbType::ArrowRight,
maliput_sys::api::rules::ffi::BulbType::kArrowUp => BulbType::ArrowUp,
maliput_sys::api::rules::ffi::BulbType::kArrowUpperLeft => BulbType::ArrowUpperLeft,
maliput_sys::api::rules::ffi::BulbType::kArrowUpperRight => BulbType::ArrowUpperRight,
maliput_sys::api::rules::ffi::BulbType::kUTurnLeft => BulbType::UTurnLeft,
maliput_sys::api::rules::ffi::BulbType::kUTurnRight => BulbType::UTurnRight,
maliput_sys::api::rules::ffi::BulbType::kWalk => BulbType::Walk,
maliput_sys::api::rules::ffi::BulbType::kDontWalk => BulbType::DontWalk,
_ => panic!("Invalid bulb type"),
}
}
pub fn position_bulb_group(&self) -> super::InertialPosition {
let inertial_position = maliput_sys::api::rules::ffi::Bulb_position_bulb_group(self.bulb);
super::InertialPosition { ip: inertial_position }
}
pub fn orientation_bulb_group(&self) -> super::Rotation {
let rotation = maliput_sys::api::rules::ffi::Bulb_orientation_bulb_group(self.bulb);
super::Rotation { r: rotation }
}
pub fn arrow_orientation_rad(&self) -> Option<f64> {
let arrow_orientation = maliput_sys::api::rules::ffi::Bulb_arrow_orientation_rad(self.bulb);
if arrow_orientation.is_null() {
return None;
}
Some(arrow_orientation.value)
}
pub fn states(&self) -> Vec<BulbState> {
let states_cpp = maliput_sys::api::rules::ffi::Bulb_states(self.bulb);
states_cpp
.into_iter()
.map(Bulb::_from_cpp_state_to_rust_state)
.collect::<Vec<BulbState>>()
}
pub fn get_default_state(&self) -> BulbState {
let default_state = self.bulb.GetDefaultState();
Bulb::_from_cpp_state_to_rust_state(&default_state)
}
pub fn is_valid_state(&self, state: &BulbState) -> bool {
self.bulb.IsValidState(&Bulb::_from_rust_state_to_cpp_state(state))
}
pub fn bounding_box(&self) -> (crate::math::Vector3, crate::math::Vector3) {
let min = maliput_sys::api::rules::ffi::Bulb_bounding_box_min(self.bulb);
let max = maliput_sys::api::rules::ffi::Bulb_bounding_box_max(self.bulb);
(crate::math::Vector3 { v: min }, crate::math::Vector3 { v: max })
}
pub fn bulb_group(&self) -> BulbGroup<'_> {
BulbGroup {
bulb_group: unsafe {
maliput_sys::api::rules::ffi::Bulb_bulb_group(self.bulb)
.as_ref()
.expect("Unable to get underlying bulb group pointer. The Bulb might not be part of any BulbGroup.")
},
}
}
fn _from_cpp_state_to_rust_state(cpp_bulb_state: &maliput_sys::api::rules::ffi::BulbState) -> BulbState {
match *cpp_bulb_state {
maliput_sys::api::rules::ffi::BulbState::kOff => BulbState::Off,
maliput_sys::api::rules::ffi::BulbState::kOn => BulbState::On,
maliput_sys::api::rules::ffi::BulbState::kBlinking => BulbState::Blinking,
_ => panic!("Invalid bulb state"),
}
}
fn _from_rust_state_to_cpp_state(rust_bulb_state: &BulbState) -> maliput_sys::api::rules::ffi::BulbState {
match rust_bulb_state {
BulbState::Off => maliput_sys::api::rules::ffi::BulbState::kOff,
BulbState::On => maliput_sys::api::rules::ffi::BulbState::kOn,
BulbState::Blinking => maliput_sys::api::rules::ffi::BulbState::kBlinking,
}
}
}
pub struct BulbGroup<'a> {
pub bulb_group: &'a maliput_sys::api::rules::ffi::BulbGroup,
}
impl BulbGroup<'_> {
pub fn unique_id(&self) -> UniqueBulbGroupId {
UniqueBulbGroupId {
unique_bulb_group_id: maliput_sys::api::rules::ffi::BulbGroup_unique_id(self.bulb_group),
}
}
pub fn id(&self) -> String {
maliput_sys::api::rules::ffi::BulbGroup_id(self.bulb_group)
}
pub fn position_traffic_light(&self) -> super::InertialPosition {
let inertial_position = maliput_sys::api::rules::ffi::BulbGroup_position_traffic_light(self.bulb_group);
super::InertialPosition { ip: inertial_position }
}
pub fn orientation_traffic_light(&self) -> super::Rotation {
let rotation = maliput_sys::api::rules::ffi::BulbGroup_orientation_traffic_light(self.bulb_group);
super::Rotation { r: rotation }
}
pub fn bulbs(&self) -> Vec<Bulb<'_>> {
let bulbs_cpp = maliput_sys::api::rules::ffi::BulbGroup_bulbs(self.bulb_group);
bulbs_cpp
.into_iter()
.map(|b| Bulb {
bulb: unsafe { b.bulb.as_ref().expect("") },
})
.collect::<Vec<Bulb>>()
}
pub fn get_bulb(&self, id: &String) -> Option<Bulb<'_>> {
let bulb = maliput_sys::api::rules::ffi::BulbGroup_GetBulb(self.bulb_group, id);
if bulb.is_null() {
return None;
}
Some(Bulb {
bulb: unsafe { bulb.as_ref().expect("Unable to get underlying bulb pointer") },
})
}
pub fn traffic_light(&self) -> TrafficLight<'_> {
TrafficLight {
traffic_light: unsafe {
maliput_sys::api::rules::ffi::BulbGroup_traffic_light(self.bulb_group)
.as_ref()
.expect("Unable to get underlying traffic light pointer. The BulbGroup might not be registered to a TrafficLight.")
},
}
}
}
pub struct UniqueBulbId {
pub(crate) unique_bulb_id: cxx::UniquePtr<maliput_sys::api::rules::ffi::UniqueBulbId>,
}
impl UniqueBulbId {
pub fn traffic_light_id(&self) -> String {
maliput_sys::api::rules::ffi::UniqueBulbId_traffic_light_id(&self.unique_bulb_id)
}
pub fn bulb_group_id(&self) -> String {
maliput_sys::api::rules::ffi::UniqueBulbId_bulb_group_id(&self.unique_bulb_id)
}
pub fn bulb_id(&self) -> String {
maliput_sys::api::rules::ffi::UniqueBulbId_bulb_id(&self.unique_bulb_id)
}
pub fn string(&self) -> String {
self.unique_bulb_id.string().to_string()
}
}
pub struct UniqueBulbGroupId {
unique_bulb_group_id: cxx::UniquePtr<maliput_sys::api::rules::ffi::UniqueBulbGroupId>,
}
impl UniqueBulbGroupId {
pub fn traffic_light_id(&self) -> String {
maliput_sys::api::rules::ffi::UniqueBulbGroupId_traffic_light_id(&self.unique_bulb_group_id)
}
pub fn bulb_group_id(&self) -> String {
maliput_sys::api::rules::ffi::UniqueBulbGroupId_bulb_group_id(&self.unique_bulb_group_id)
}
pub fn string(&self) -> String {
self.unique_bulb_group_id.string().to_string()
}
}
pub struct RuleRegistry<'a> {
pub(super) rule_registry: &'a maliput_sys::api::rules::ffi::RuleRegistry,
}
pub enum RuleValuesByType {
DiscreteValues(Vec<DiscreteValue>),
Ranges(Vec<Range>),
}
impl<'a> RuleRegistry<'a> {
pub fn get_discrete_value_rule_types(&self) -> Vec<String> {
let discrete_value_types =
maliput_sys::api::rules::ffi::RuleRegistry_DiscreteValueRuleTypes(self.rule_registry);
let discrete_value_types = discrete_value_types
.as_ref()
.expect("Unable to get underlying discrete value rule types pointer.");
discrete_value_types.iter().map(|dvt| dvt.type_id.clone()).collect()
}
pub fn discrete_values_by_type(&self, rule_type_id: String) -> Option<Vec<DiscreteValue>> {
let discrete_value_types =
maliput_sys::api::rules::ffi::RuleRegistry_DiscreteValueRuleTypes(self.rule_registry);
let discrete_value_types = discrete_value_types
.as_ref()
.expect("Unable to get underlying discrete value rule types pointer.");
discrete_value_types
.iter()
.find(|dvt| dvt.type_id == rule_type_id)
.map(|dvt| discrete_values_from_cxx(&dvt.values))
}
pub fn get_range_rule_types(&self) -> Vec<String> {
let range_value_types = maliput_sys::api::rules::ffi::RuleRegistry_RangeValueRuleTypes(self.rule_registry);
let range_value_types = range_value_types
.as_ref()
.expect("Unable to get underlying range rule types pointer.");
range_value_types.iter().map(|rvt| rvt.type_id.clone()).collect()
}
pub fn range_values_by_type(&self, rule_type_id: String) -> Option<Vec<Range>> {
let range_value_types = maliput_sys::api::rules::ffi::RuleRegistry_RangeValueRuleTypes(self.rule_registry);
let range_value_types = range_value_types
.as_ref()
.expect("Unable to get underlying range rule types pointer.");
range_value_types
.iter()
.find(|rvt| rvt.type_id == rule_type_id)
.map(|rvt| range_values_from_cxx(&rvt.values))
}
pub fn get_possible_states_of_rule_type(&self, rule_type_id: String) -> Option<RuleValuesByType> {
if let Some(ranges) = self.range_values_by_type(rule_type_id.clone()) {
Some(RuleValuesByType::Ranges(ranges))
} else {
self.discrete_values_by_type(rule_type_id)
.map(RuleValuesByType::DiscreteValues)
}
}
}
pub struct QueryResults {
pub discrete_value_rules: std::collections::HashMap<String, DiscreteValueRule>,
pub range_value_rules: std::collections::HashMap<String, RangeValueRule>,
}
pub struct RoadRulebook<'a> {
pub(super) road_rulebook: &'a maliput_sys::api::rules::ffi::RoadRulebook,
}
impl<'a> RoadRulebook<'a> {
pub fn get_discrete_value_rule(&self, rule_id: &String) -> Option<DiscreteValueRule> {
let discrete_value_rule =
maliput_sys::api::rules::ffi::RoadRulebook_GetDiscreteValueRule(self.road_rulebook, rule_id);
if discrete_value_rule.is_null() {
return None;
}
Some(DiscreteValueRule { discrete_value_rule })
}
pub fn get_range_value_rule(&self, rule_id: &String) -> Option<RangeValueRule> {
let range_value_rule =
maliput_sys::api::rules::ffi::RoadRulebook_GetRangeValueRule(self.road_rulebook, rule_id);
if range_value_rule.is_null() {
return None;
}
Some(RangeValueRule { range_value_rule })
}
pub fn rules(&self) -> QueryResults {
let query_results_cpp = maliput_sys::api::rules::ffi::RoadRulebook_Rules(self.road_rulebook);
let discrete_value_rules_id =
maliput_sys::api::rules::ffi::QueryResults_discrete_value_rules(&query_results_cpp);
let range_value_rules_id = maliput_sys::api::rules::ffi::QueryResults_range_value_rules(&query_results_cpp);
let mut dvr_map = std::collections::HashMap::new();
for rule_id in discrete_value_rules_id {
let rule = self.get_discrete_value_rule(&rule_id).unwrap();
dvr_map.insert(rule.id(), rule);
}
let mut rvr_map = std::collections::HashMap::new();
for rule_id in range_value_rules_id {
let rule = self.get_range_value_rule(&rule_id).unwrap();
rvr_map.insert(rule.id(), rule);
}
QueryResults {
discrete_value_rules: dvr_map,
range_value_rules: rvr_map,
}
}
pub fn find_rules(&self, ranges: &Vec<super::LaneSRange>, tolerance: f64) -> Result<QueryResults, MaliputError> {
let mut ranges_cpp = Vec::new();
for range in ranges {
ranges_cpp.push(maliput_sys::api::rules::ffi::ConstLaneSRangeRef {
lane_s_range: &range.lane_s_range,
});
}
let query_results_cpp =
maliput_sys::api::rules::ffi::RoadRulebook_FindRules(self.road_rulebook, &ranges_cpp, tolerance)?;
let discrete_value_rules_id =
maliput_sys::api::rules::ffi::QueryResults_discrete_value_rules(&query_results_cpp);
let range_value_rules_id = maliput_sys::api::rules::ffi::QueryResults_range_value_rules(&query_results_cpp);
let mut dvr_map = std::collections::HashMap::new();
for rule_id in discrete_value_rules_id {
if let Some(rule) = self.get_discrete_value_rule(&rule_id) {
dvr_map.insert(rule.id(), rule);
}
}
let mut rvr_map = std::collections::HashMap::new();
for rule_id in range_value_rules_id {
if let Some(rule) = self.get_range_value_rule(&rule_id) {
rvr_map.insert(rule.id(), rule);
}
}
Ok(QueryResults {
discrete_value_rules: dvr_map,
range_value_rules: rvr_map,
})
}
}
pub struct DiscreteValueRule {
discrete_value_rule: cxx::UniquePtr<maliput_sys::api::rules::ffi::DiscreteValueRule>,
}
impl DiscreteValueRule {
pub fn id(&self) -> String {
maliput_sys::api::rules::ffi::DiscreteValueRule_id(&self.discrete_value_rule)
}
pub fn type_id(&self) -> String {
maliput_sys::api::rules::ffi::DiscreteValueRule_type_id(&self.discrete_value_rule)
}
pub fn zone(&self) -> super::LaneSRoute {
let lane_s_route = maliput_sys::api::rules::ffi::DiscreteValueRule_zone(&self.discrete_value_rule);
super::LaneSRoute { lane_s_route }
}
pub fn states(&self) -> Vec<DiscreteValue> {
discrete_values_from_cxx(self.discrete_value_rule.states())
}
}
impl std::fmt::Debug for DiscreteValueRule {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"DiscreteValueRule {{ id: {}, type_id: {}, zone: {:?}, states: {:?} }}",
self.id(),
self.type_id(),
self.zone(),
self.states()
)
}
}
pub struct DiscreteValueRuleState {
pub rule_id: String,
pub state: DiscreteValue,
}
pub struct RangeValueRule {
range_value_rule: cxx::UniquePtr<maliput_sys::api::rules::ffi::RangeValueRule>,
}
impl RangeValueRule {
pub fn id(&self) -> String {
maliput_sys::api::rules::ffi::RangeValueRule_id(&self.range_value_rule)
}
pub fn type_id(&self) -> String {
maliput_sys::api::rules::ffi::RangeValueRule_type_id(&self.range_value_rule)
}
pub fn zone(&self) -> super::LaneSRoute {
let lane_s_route = maliput_sys::api::rules::ffi::RangeValueRule_zone(&self.range_value_rule);
super::LaneSRoute { lane_s_route }
}
pub fn states(&self) -> Vec<Range> {
range_values_from_cxx(self.range_value_rule.states())
}
}
#[derive(Display, IntoStaticStr)]
pub enum RuleType {
#[strum(serialize = "Direction-Usage Rule Type")]
DirectionUsage,
#[strum(serialize = "Right-Of-Way Rule Type")]
RightOfWay,
#[strum(serialize = "Vehicle-Stop-In-Zone-Behavior Rule Type")]
VehicleStopInZoneBehavior,
#[strum(serialize = "Speed-Limit Rule Type")]
SpeedLimit,
}
impl RuleType {
pub fn get_rule_id(&self, lane_id: &str) -> String {
self.to_string() + "/" + lane_id
}
}
pub struct RuleStateBase {
severity: i32,
related_rules: cxx::UniquePtr<cxx::CxxVector<maliput_sys::api::rules::ffi::RelatedRule>>,
related_unique_ids: cxx::UniquePtr<cxx::CxxVector<maliput_sys::api::rules::ffi::RelatedUniqueId>>,
}
pub trait RuleState {
fn get_rule_state(&self) -> &RuleStateBase;
fn severity(&self) -> i32 {
self.get_rule_state().severity
}
fn related_rules(&self) -> std::collections::HashMap<&String, &Vec<String>> {
self.get_rule_state()
.related_rules
.iter()
.map(|rr| (&rr.group_name, &rr.rule_ids))
.collect::<std::collections::HashMap<&String, &Vec<String>>>()
}
fn related_unique_ids(&self) -> std::collections::HashMap<&String, &Vec<String>> {
self.get_rule_state()
.related_unique_ids
.iter()
.map(|rui| (&rui.group_name, &rui.unique_ids))
.collect::<std::collections::HashMap<&String, &Vec<String>>>()
}
}
pub struct DiscreteValue {
rule_state: RuleStateBase,
value: String,
}
impl RuleState for DiscreteValue {
fn get_rule_state(&self) -> &RuleStateBase {
&self.rule_state
}
}
impl DiscreteValue {
pub fn value(&self) -> &String {
&self.value
}
}
impl std::fmt::Debug for DiscreteValue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"DiscreteValue {{ value: {}, severity: {}, related_rules: {:?}, related_unique_ids: {:?} }}",
self.value(),
self.severity(),
self.related_rules(),
self.related_unique_ids()
)
}
}
pub struct Range {
rule_state: RuleStateBase,
description: String,
min: f64,
max: f64,
}
impl RuleState for Range {
fn get_rule_state(&self) -> &RuleStateBase {
&self.rule_state
}
}
impl Range {
pub fn description(&self) -> &String {
&self.description
}
pub fn min(&self) -> f64 {
self.min
}
pub fn max(&self) -> f64 {
self.max
}
}
pub struct Phase {
phase: cxx::UniquePtr<maliput_sys::api::rules::ffi::Phase>,
}
impl Phase {
pub fn id(&self) -> String {
maliput_sys::api::rules::ffi::Phase_id(&self.phase)
}
pub fn discrete_value_rule_states(&self) -> HashMap<String, DiscreteValue> {
let rule_states = maliput_sys::api::rules::ffi::Phase_discrete_value_rule_states(&self.phase);
rule_states
.iter()
.map(|state| {
(
state.rule_id.clone(),
discrete_value_from_discrete_value_cxx(&state.state),
)
})
.collect()
}
pub fn unique_bulb_ids(&self) -> Vec<UniqueBulbId> {
let unique_bulb_ids = maliput_sys::api::rules::ffi::Phase_unique_bulb_ids(&self.phase);
unique_bulb_ids
.iter()
.map(|bulb_id| UniqueBulbId {
unique_bulb_id: maliput_sys::api::rules::ffi::ptr_from_unique_bulb_id(bulb_id),
})
.collect()
}
pub fn bulb_state(&self, unique_bulb_id: &UniqueBulbId) -> Option<BulbState> {
let bulb_state = maliput_sys::api::rules::ffi::Phase_bulb_state(&self.phase, &unique_bulb_id.unique_bulb_id);
if bulb_state.is_null() {
return None;
}
Some(match *bulb_state {
maliput_sys::api::rules::ffi::BulbState::kOff => BulbState::Off,
maliput_sys::api::rules::ffi::BulbState::kOn => BulbState::On,
maliput_sys::api::rules::ffi::BulbState::kBlinking => BulbState::Blinking,
_ => return None,
})
}
}
pub struct NextPhase {
pub next_phase: Phase,
pub duration_until: Option<f64>,
}
pub struct PhaseRing {
phase_ring: cxx::UniquePtr<maliput_sys::api::rules::ffi::PhaseRing>,
}
impl PhaseRing {
pub fn id(&self) -> String {
maliput_sys::api::rules::ffi::PhaseRing_id(&self.phase_ring)
}
pub fn get_phase(&self, id: &String) -> Option<Phase> {
let phase = maliput_sys::api::rules::ffi::PhaseRing_GetPhase(&self.phase_ring, id);
if phase.is_null() {
return None;
}
Some(Phase { phase })
}
pub fn phases(&self) -> Vec<String> {
maliput_sys::api::rules::ffi::PhaseRing_phases_ids(&self.phase_ring)
}
pub fn get_next_phases(&self, id: &String) -> Result<Vec<NextPhase>, MaliputError> {
let next_phases = maliput_sys::api::rules::ffi::PhaseRing_GetNextPhases(&self.phase_ring, id)?;
Ok(next_phases
.iter()
.map(|np| NextPhase {
next_phase: Phase {
phase: maliput_sys::api::rules::ffi::PhaseRing_GetPhase(&self.phase_ring, &np.phase_id),
},
duration_until: if np.duration_until.is_null() {
None
} else {
Some(np.duration_until.value)
},
})
.collect())
}
}
pub struct PhaseRingBook<'a> {
pub(super) phase_ring_book: &'a maliput_sys::api::rules::ffi::PhaseRingBook,
}
impl<'a> PhaseRingBook<'a> {
pub fn get_phase_rings_ids(&self) -> Vec<String> {
maliput_sys::api::rules::ffi::PhaseRingBook_GetPhaseRingsId(self.phase_ring_book)
}
pub fn get_phase_ring(&self, phase_ring_id: &String) -> Option<PhaseRing> {
let phase_ring = maliput_sys::api::rules::ffi::PhaseRingBook_GetPhaseRing(self.phase_ring_book, phase_ring_id);
if phase_ring.is_null() {
return None;
}
Some(PhaseRing { phase_ring })
}
pub fn find_phase_ring(&self, rule_id: &String) -> Option<PhaseRing> {
let phase_ring = maliput_sys::api::rules::ffi::PhaseRingBook_FindPhaseRing(self.phase_ring_book, rule_id);
if phase_ring.is_null() {
return None;
}
Some(PhaseRing { phase_ring })
}
}
pub struct NextState<T> {
pub next_state: T,
pub duration_until: Option<f64>,
}
pub struct StateProviderQuery<T> {
pub state: T,
pub next: Option<NextState<T>>,
}
pub type PhaseStateProviderQuery = StateProviderQuery<String>;
pub struct PhaseProvider<'a> {
pub(super) phase_provider: &'a maliput_sys::api::rules::ffi::PhaseProvider,
}
impl<'a> PhaseProvider<'a> {
pub fn get_phase(&self, phase_ring_id: &String) -> Option<PhaseStateProviderQuery> {
let phase_state = maliput_sys::api::rules::ffi::PhaseProvider_GetPhase(self.phase_provider, phase_ring_id);
if phase_state.is_null() {
return None;
}
let next_state = maliput_sys::api::rules::ffi::PhaseStateProvider_next(&phase_state);
let next_phase = if next_state.is_null() {
None
} else {
Some(NextState {
next_state: next_state.phase_id.clone(),
duration_until: if next_state.duration_until.is_null() {
None
} else {
Some(next_state.duration_until.value)
},
})
};
Some(StateProviderQuery {
state: maliput_sys::api::rules::ffi::PhaseStateProvider_state(&phase_state),
next: next_phase,
})
}
}
pub struct DiscreteValueRuleStateProvider<'a> {
pub(super) state_provider: &'a maliput_sys::api::rules::ffi::DiscreteValueRuleStateProvider,
}
impl<'a> DiscreteValueRuleStateProvider<'a> {
pub fn get_state_by_rule_id(&self, rule_id: &String) -> Option<StateProviderQuery<DiscreteValue>> {
let query_state =
maliput_sys::api::rules::ffi::DiscreteValueRuleStateProvider_GetStateById(self.state_provider, rule_id);
Self::next_state_from_cxx_query(query_state)
}
pub fn get_state_by_rule_type(
&self,
road_position: &RoadPosition,
rule_type: RuleType,
tolerance: f64,
) -> Option<StateProviderQuery<DiscreteValue>> {
let query_state = maliput_sys::api::rules::ffi::DiscreteValueRuleStateProvider_GetStateByType(
self.state_provider,
&road_position.rp,
&rule_type.to_string(),
tolerance,
);
Self::next_state_from_cxx_query(query_state)
}
fn next_state_from_cxx_query(
query_state: cxx::UniquePtr<maliput_sys::api::rules::ffi::DiscreteValueRuleStateProviderQuery>,
) -> Option<StateProviderQuery<DiscreteValue>> {
if query_state.is_null() {
return None;
}
let next_state = maliput_sys::api::rules::ffi::DiscreteValueRuleStateProviderQuery_next(&query_state);
Some(StateProviderQuery {
state: discrete_value_from_discrete_value_cxx(
&maliput_sys::api::rules::ffi::DiscreteValueRuleStateProviderQuery_state(&query_state),
),
next: if next_state.is_null() {
None
} else {
Some(NextState {
next_state: discrete_value_from_discrete_value_cxx(&next_state.state),
duration_until: if next_state.duration_until.is_null() {
None
} else {
Some(next_state.duration_until.value)
},
})
},
})
}
}
pub struct RangeValueRuleStateProvider<'a> {
pub(super) state_provider: &'a maliput_sys::api::rules::ffi::RangeValueRuleStateProvider,
}
impl<'a> RangeValueRuleStateProvider<'a> {
pub fn get_state_by_rule_id(&self, rule_id: &String) -> Option<StateProviderQuery<Range>> {
let query_state =
maliput_sys::api::rules::ffi::RangeValueRuleStateProvider_GetStateById(self.state_provider, rule_id);
Self::next_state_from_cxx_query(query_state)
}
pub fn get_state_by_rule_type(
&self,
road_position: &RoadPosition,
rule_type: RuleType,
tolerance: f64,
) -> Option<StateProviderQuery<Range>> {
let query_state = maliput_sys::api::rules::ffi::RangeValueRuleStateProvider_GetStateByType(
self.state_provider,
&road_position.rp,
&rule_type.to_string(),
tolerance,
);
Self::next_state_from_cxx_query(query_state)
}
fn next_state_from_cxx_query(
query_state: cxx::UniquePtr<maliput_sys::api::rules::ffi::RangeValueRuleStateProviderQuery>,
) -> Option<StateProviderQuery<Range>> {
if query_state.is_null() {
return None;
}
let next_state = maliput_sys::api::rules::ffi::RangeValueRuleStateProviderQuery_next(&query_state);
Some(StateProviderQuery {
state: range_value_from_range_value_cxx(
&maliput_sys::api::rules::ffi::RangeValueRuleStateProviderQuery_state(&query_state),
),
next: if next_state.is_null() {
None
} else {
Some(NextState {
next_state: range_value_from_range_value_cxx(&next_state.state),
duration_until: if next_state.duration_until.is_null() {
None
} else {
Some(next_state.duration_until.value)
},
})
},
})
}
}
fn range_values_from_cxx(
range_values_cxx: &cxx::Vector<maliput_sys::api::rules::ffi::RangeValueRuleRange>,
) -> Vec<Range> {
range_values_cxx
.iter()
.map(|range| Range {
rule_state: RuleStateBase {
severity: maliput_sys::api::rules::ffi::RangeValueRuleRange_severity(range),
related_rules: maliput_sys::api::rules::ffi::RangeValueRuleRange_related_rules(range),
related_unique_ids: maliput_sys::api::rules::ffi::RangeValueRuleRange_related_unique_ids(range),
},
description: maliput_sys::api::rules::ffi::RangeValueRuleRange_description(range),
min: maliput_sys::api::rules::ffi::RangeValueRuleRange_min(range),
max: maliput_sys::api::rules::ffi::RangeValueRuleRange_max(range),
})
.collect()
}
fn discrete_values_from_cxx(
discrete_values_cxx: &cxx::Vector<maliput_sys::api::rules::ffi::DiscreteValueRuleDiscreteValue>,
) -> Vec<DiscreteValue> {
discrete_values_cxx
.iter()
.map(discrete_value_from_discrete_value_cxx)
.collect()
}
pub(crate) fn discrete_value_from_discrete_value_cxx(
discrete_value: &maliput_sys::api::rules::ffi::DiscreteValueRuleDiscreteValue,
) -> DiscreteValue {
DiscreteValue {
rule_state: RuleStateBase {
severity: maliput_sys::api::rules::ffi::DiscreteValueRuleDiscreteValue_severity(discrete_value),
related_rules: maliput_sys::api::rules::ffi::DiscreteValueRuleDiscreteValue_related_rules(discrete_value),
related_unique_ids: maliput_sys::api::rules::ffi::DiscreteValueRuleDiscreteValue_related_unique_ids(
discrete_value,
),
},
value: maliput_sys::api::rules::ffi::DiscreteValueRuleDiscreteValue_value(discrete_value),
}
}
fn range_value_from_range_value_cxx(range: &maliput_sys::api::rules::ffi::RangeValueRuleRange) -> Range {
Range {
rule_state: RuleStateBase {
severity: maliput_sys::api::rules::ffi::RangeValueRuleRange_severity(range),
related_rules: maliput_sys::api::rules::ffi::RangeValueRuleRange_related_rules(range),
related_unique_ids: maliput_sys::api::rules::ffi::RangeValueRuleRange_related_unique_ids(range),
},
description: maliput_sys::api::rules::ffi::RangeValueRuleRange_description(range),
min: maliput_sys::api::rules::ffi::RangeValueRuleRange_min(range),
max: maliput_sys::api::rules::ffi::RangeValueRuleRange_max(range),
}
}