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