maliput/common/
mod.rs

1// BSD 3-Clause License
2//
3// Copyright (c) 2025, Woven by Toyota.
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are met:
8//
9// * Redistributions of source code must retain the above copyright notice, this
10//   list of conditions and the following disclaimer.
11//
12// * Redistributions in binary form must reproduce the above copyright notice,
13//   this list of conditions and the following disclaimer in the documentation
14//   and/or other materials provided with the distribution.
15//
16// * Neither the name of the copyright holder nor the names of its
17//   contributors may be used to endorse or promote products derived from
18//   this software without specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31/// Error types for maliput lib.
32#[derive(Debug, PartialEq, Eq, thiserror::Error)]
33pub enum MaliputError {
34    #[error("Maliput Road Network description parser error: {0}")]
35    RoadNetworkDescriptionParserError(String),
36    #[error("Maliput Road Geometry construction error: {0}")]
37    RoadGeometryConstructionError(String),
38    #[error("Maliput Rulebook error: {0}")]
39    RulebookError(String),
40    #[error("Maliput Rule Registry error: {0}")]
41    RuleRegistryError(String),
42    #[error("Maliput Traffic Light book error: {0}")]
43    TrafficLightBookError(String),
44    #[error("Maliput Phase book error: {0}")]
45    PhaseBookError(String),
46    #[error("Maliput State Provider error: {0}")]
47    StateProviderError(String),
48    #[error("Maliput assertion error: {0}")]
49    AssertionError(String),
50    #[error("Maliput OBJ creation error: {0}")]
51    ObjCreationError(String),
52    #[error("Other: {0}")]
53    Other(String),
54}
55
56impl From<cxx::Exception> for MaliputError {
57    fn from(e: cxx::Exception) -> Self {
58        let msg = e.to_string();
59        if msg.contains("maliput::common::road_network_description_parser_error") {
60            MaliputError::RoadNetworkDescriptionParserError(msg)
61        } else if msg.contains("maliput::common::road_geometry_construction_error") {
62            MaliputError::RoadGeometryConstructionError(msg)
63        } else if msg.contains("maliput::common::rulebook_error") {
64            MaliputError::RulebookError(msg)
65        } else if msg.contains("maliput::common::rule_registry_error") {
66            MaliputError::RuleRegistryError(msg)
67        } else if msg.contains("maliput::common::traffic_light_book_error") {
68            MaliputError::TrafficLightBookError(msg)
69        } else if msg.contains("maliput::common::phase_book_error") {
70            MaliputError::PhaseBookError(msg)
71        } else if msg.contains("maliput::common::state_provider_error") {
72            MaliputError::StateProviderError(msg)
73        } else if msg.contains("maliput::common::assertion_error") {
74            MaliputError::AssertionError(msg)
75        } else {
76            MaliputError::Other(msg)
77        }
78    }
79}
80
81/// Log levels for the under the hood maliput library's logging system.
82///
83/// See https://github.com/maliput/maliput/blob/main/include/maliput/common/logger.h
84/// for more details on the logging system and available log levels.
85#[derive(Debug, Clone, Copy, PartialEq, Eq)]
86pub enum LogLevel {
87    Off,
88    Trace,
89    Debug,
90    Info,
91    Warn,
92    Error,
93    Critical,
94    Unchanged,
95}
96
97impl From<LogLevel> for &'static str {
98    fn from(level: LogLevel) -> Self {
99        match level {
100            LogLevel::Off => "off",
101            LogLevel::Trace => "trace",
102            LogLevel::Debug => "debug",
103            LogLevel::Info => "info",
104            LogLevel::Warn => "warn",
105            LogLevel::Error => "error",
106            LogLevel::Critical => "critical",
107            LogLevel::Unchanged => "unchanged",
108        }
109    }
110}
111impl From<String> for LogLevel {
112    fn from(level: String) -> Self {
113        match level.as_str() {
114            "off" => LogLevel::Off,
115            "trace" => LogLevel::Trace,
116            "debug" => LogLevel::Debug,
117            "info" => LogLevel::Info,
118            "warn" => LogLevel::Warn,
119            "error" => LogLevel::Error,
120            "critical" => LogLevel::Critical,
121            "unchanged" => LogLevel::Unchanged,
122            _ => panic!("Invalid log level: {}", level),
123        }
124    }
125}
126impl std::fmt::Display for LogLevel {
127    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128        match self {
129            LogLevel::Off => write!(f, "off"),
130            LogLevel::Trace => write!(f, "trace"),
131            LogLevel::Debug => write!(f, "debug"),
132            LogLevel::Info => write!(f, "info"),
133            LogLevel::Warn => write!(f, "warn"),
134            LogLevel::Error => write!(f, "error"),
135            LogLevel::Critical => write!(f, "critical"),
136            LogLevel::Unchanged => write!(f, "unchanged"),
137        }
138    }
139}
140
141/// Set the log level for the maliput library's logging system.
142///
143/// # Arguments
144///
145/// * `level` - The desired log level to set. This should be one of the variants of `LogLevel`.
146///
147/// # Returns
148///
149/// A string indicating the previous log level before the change.
150///
151pub fn set_log_level(level: LogLevel) -> LogLevel {
152    maliput_sys::common::ffi::LOG_set_log_level(level.into()).into()
153}
154
155#[cfg(test)]
156mod tests {
157    use super::set_log_level;
158    use super::LogLevel;
159    #[test]
160    fn test_log_level() {
161        set_log_level(LogLevel::Off);
162        let last_level = set_log_level(LogLevel::Trace);
163        assert_eq!(last_level, LogLevel::Off);
164        let last_level = set_log_level(LogLevel::Debug);
165        assert_eq!(last_level, LogLevel::Trace);
166        let last_level = set_log_level(LogLevel::Info);
167        assert_eq!(last_level, LogLevel::Debug);
168        let last_level = set_log_level(LogLevel::Warn);
169        assert_eq!(last_level, LogLevel::Info);
170        let last_level = set_log_level(LogLevel::Error);
171        assert_eq!(last_level, LogLevel::Warn);
172        let last_level = set_log_level(LogLevel::Critical);
173        assert_eq!(last_level, LogLevel::Error);
174        let last_level = set_log_level(LogLevel::Unchanged);
175        assert_eq!(last_level, LogLevel::Critical);
176        let last_level = set_log_level(LogLevel::Off);
177        assert_eq!(last_level, LogLevel::Critical);
178        // TODO(francocipollone): Test an invalid log level. It throws under the hood in c++.
179    }
180}