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}