maliput/
lib.rs

1// BSD 3-Clause License
2//
3// Copyright (c) 2024, 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#![allow(rustdoc::bare_urls)]
31#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))]
32
33#[allow(clippy::needless_lifetimes)]
34// Remove after rust 1.87 is used. https://github.com/rust-lang/rust-clippy/issues/14441
35pub mod api;
36pub mod common;
37pub mod math;
38pub mod utility;
39
40/// # ResourceManager
41///
42/// Convenient method for getting the path to the resources of the backends.
43///
44/// # Backends
45///  - maliput_malidrive: Resources from maliput_malidrive are brought by maliput-sdk package.
46///    All the maliput_malidrive resources are stored in the same directory:
47///    (See https://github.com/maliput/maliput_malidrive/tree/main/resources)
48///
49/// # Example
50///
51/// How to get all the resources from the maliput_malidrive backend:
52///
53/// ```rust, no_run
54/// let resource_manager = maliput::ResourceManager::new();
55/// let all_resources_in_malidrive = resource_manager.get_all_resources_by_backend("maliput_malidrive");
56/// ```
57///
58/// How to get the path to the TShapeRoad.xodr file from the maliput_malidrive backend:
59/// ```rust, no_run
60/// let resource_manager = maliput::ResourceManager::new();
61/// let t_shape_road_xodr_path = resource_manager.get_resource_path_by_name("maliput_malidrive", "TShapeRoad.xodr");
62/// assert!(t_shape_road_xodr_path.is_some());
63/// assert!(t_shape_road_xodr_path.unwrap().exists());
64/// ```
65pub struct ResourceManager {
66    resource_paths: std::collections::HashMap<String, Vec<std::path::PathBuf>>,
67}
68
69impl Default for ResourceManager {
70    fn default() -> Self {
71        Self::new()
72    }
73}
74
75impl ResourceManager {
76    /// Creates a new ResourceManager.
77    pub fn new() -> ResourceManager {
78        let mut resource_paths = std::collections::HashMap::new();
79        maliput_sdk::sdk_resources()
80            .iter()
81            .for_each(|(backend_name, resource_path)| {
82                // All the files in the path are added to the resource manager
83                let files = std::fs::read_dir(resource_path).unwrap();
84                let mut paths = vec![];
85                files.filter(|file| file.is_ok()).for_each(|file| {
86                    paths.push(file.unwrap().path());
87                });
88                resource_paths.insert(backend_name.clone(), paths);
89            });
90        ResourceManager { resource_paths }
91    }
92
93    /// Obtains the path to a resource by its name.
94    /// # Arguments
95    ///
96    /// * `backend_name` - The name of the backend.
97    /// * `resource_name` - The name of the resource.
98    ///
99    /// # Returns
100    /// The path to the resource if it exists, otherwise None.
101    pub fn get_resource_path_by_name(&self, backend_name: &str, resource_name: &str) -> Option<std::path::PathBuf> {
102        let paths = self.resource_paths.get(backend_name).unwrap();
103        for path in paths {
104            if path.to_str().unwrap().contains(resource_name) {
105                return Some(path.clone());
106            }
107        }
108        None
109    }
110
111    /// Obtains all the resources from a backend.
112    /// # Arguments
113    ///
114    /// * `backend_name` - The name of the backend.
115    ///
116    /// # Returns
117    /// A vector with all the resources from the backend if it exists, otherwise None.
118    pub fn get_all_resources_by_backend(&self, backend_name: &str) -> Option<&Vec<std::path::PathBuf>> {
119        self.resource_paths.get(backend_name)
120    }
121
122    /// Get the underlying collection that stores all the resources for each backend.
123    pub fn get_all_resources(&self) -> &std::collections::HashMap<String, Vec<std::path::PathBuf>> {
124        &self.resource_paths
125    }
126}
127
128// test
129
130mod tests {
131
132    #[test]
133    fn test_maliput_malidrive_resources() {
134        let resource_manager = crate::ResourceManager::new();
135
136        let t_shape_road_xodr_path = resource_manager.get_resource_path_by_name("maliput_malidrive", "TShapeRoad.xodr");
137        assert!(t_shape_road_xodr_path.is_some());
138        assert!(t_shape_road_xodr_path.unwrap().exists());
139
140        let wrong_file_path = resource_manager.get_resource_path_by_name("maliput_malidrive", "wrong_file");
141        assert!(wrong_file_path.is_none());
142
143        let all_resources_in_malidrive = resource_manager.get_all_resources_by_backend("maliput_malidrive");
144        assert!(all_resources_in_malidrive.is_some());
145        assert!(all_resources_in_malidrive.unwrap().len() > 10);
146
147        let all_resources_in_wrong_backend = resource_manager.get_all_resources_by_backend("wrong_backend");
148        assert!(all_resources_in_wrong_backend.is_none());
149
150        let all_resources = resource_manager.get_all_resources();
151        // There is only one backend supported at the moment.
152        assert_eq!(all_resources.len(), 1);
153    }
154}