Skip to main content

nautilus_core/
paths.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2026 Nautech Systems Pty Ltd. All rights reserved.
3//  https://nautechsystems.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16//! Utility functions for resolving project and workspace directory paths.
17
18use std::path::PathBuf;
19
20/// Returns the workspace root directory path.
21///
22/// This is the directory containing the top-level `Cargo.toml` with the
23/// `[workspace]` section, typically where `python/` and `docs/` are located.
24///
25/// # Panics
26///
27/// Panics if the `CARGO_MANIFEST_DIR` environment variable is not set or
28/// the parent directories cannot be determined.
29#[must_use]
30pub fn get_workspace_root_path() -> PathBuf {
31    PathBuf::from(env!("CARGO_MANIFEST_DIR"))
32        .parent() // crates/core -> crates/
33        .and_then(|p| p.parent()) // crates/ -> nautilus_trader/
34        .expect("Failed to get workspace root")
35        .to_path_buf()
36}
37
38/// Returns the project root directory path.
39///
40/// For this monorepo, the project root is the same as the workspace root.
41///
42/// # Panics
43///
44/// Panics if the workspace root path cannot be determined.
45#[must_use]
46pub fn get_project_root_path() -> PathBuf {
47    get_workspace_root_path()
48}
49
50/// Returns the test data directory path.
51#[must_use]
52pub fn get_test_data_path() -> PathBuf {
53    if let Ok(test_data_root_path) = std::env::var("TEST_DATA_ROOT_PATH") {
54        get_project_root_path()
55            .join(test_data_root_path)
56            .join("test_data")
57    } else {
58        get_project_root_path().join("test_data")
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use rstest::rstest;
65
66    use super::*;
67
68    #[rstest]
69    fn test_workspace_root_contains_python_pyproject() {
70        let root = get_workspace_root_path();
71        assert!(
72            root.join("python/pyproject.toml").is_file(),
73            "Workspace root should contain python/pyproject.toml, was: {root:?}"
74        );
75    }
76
77    #[rstest]
78    fn test_workspace_root_contains_crates_dir() {
79        let root = get_workspace_root_path();
80        assert!(
81            root.join("crates").is_dir(),
82            "Workspace root should contain crates/ directory, was: {root:?}"
83        );
84    }
85
86    #[rstest]
87    fn test_project_root_equals_workspace_root() {
88        assert_eq!(get_project_root_path(), get_workspace_root_path());
89    }
90
91    #[rstest]
92    fn test_test_data_path_contains_checksum_manifest() {
93        let test_data = get_test_data_path();
94        assert!(
95            test_data.join("large/checksums.json").is_file(),
96            "Test data should contain the large-file checksum manifest, path: {test_data:?}"
97        );
98    }
99}