#![allow(dead_code)]
pub const PROJECT_CONFIG: &str = "mecha10.json";
pub mod project {
pub const NODES_DIR: &str = "nodes";
pub const DRIVERS_DIR: &str = "drivers";
pub const TYPES_DIR: &str = "types";
pub const BEHAVIORS_DIR: &str = "configs/behaviors";
pub const ASSETS_DIR: &str = "assets";
pub const ASSETS_IMAGES_DIR: &str = "assets/images";
pub const MODELS_DIR: &str = "models";
pub const LOGS_DIR: &str = "logs";
pub const SIMULATION_DIR: &str = "simulation";
pub const SIMULATION_MODELS_DIR: &str = "simulation/models";
pub const SIMULATION_ENVIRONMENTS_DIR: &str = "simulation/environments";
pub const SIMULATION_TASKS_DIR: &str = "simulation/tasks";
pub fn model_config(model_name: &str) -> String {
format!("simulation/models/{}/model.json", model_name)
}
pub fn environment_config(env_name: &str) -> String {
format!("simulation/environments/{}/environment.json", env_name)
}
pub const SIMULATION_OUTPUT_DIR: &str = "simulation/output";
pub const TARGET_DIR: &str = "target";
pub const SRC_DIR: &str = "src";
pub const STATE_DIR: &str = ".mecha10";
pub const DEV_PREFLIGHT_CACHE_FILE: &str = ".mecha10/dev-preflight-cache.json";
}
pub mod config {
use super::project;
pub const DIR: &str = "configs";
pub const NODES_DIR: &str = "configs/nodes";
pub const NODES_MECHA10_DIR: &str = "configs/nodes/@mecha10";
pub const SIMULATION_DIR: &str = "configs/simulation";
pub const SIMULATION_CONFIG: &str = "configs/simulation/config.json";
fn framework_config(category_dir: &str, name: &str) -> String {
format!("{category_dir}/@mecha10/{name}/config.json")
}
fn project_config(category_dir: &str, name: &str) -> String {
format!("{category_dir}/{name}/config.json")
}
fn config_candidates(category_dir: &str, name: &str) -> [String; 2] {
[framework_config(category_dir, name), project_config(category_dir, name)]
}
pub fn framework_node(node_name: &str) -> String {
framework_config(NODES_DIR, node_name)
}
pub fn project_node(node_name: &str) -> String {
project_config(NODES_DIR, node_name)
}
pub fn framework_node_dir(node_name: &str) -> String {
format!("{}/{}", NODES_MECHA10_DIR, node_name)
}
pub fn node_config_candidates(node_name: &str) -> [String; 2] {
config_candidates(NODES_DIR, node_name)
}
pub fn framework_behavior(behavior_name: &str) -> String {
framework_config(project::BEHAVIORS_DIR, behavior_name)
}
pub fn project_behavior(behavior_name: &str) -> String {
project_config(project::BEHAVIORS_DIR, behavior_name)
}
pub fn behavior_config_candidates(behavior_name: &str) -> [String; 2] {
[project_behavior(behavior_name), framework_behavior(behavior_name)]
}
}
pub mod docker {
pub const DIR: &str = "docker";
pub const COMPOSE_FILE: &str = "docker/docker-compose.yml";
pub const COMPOSE_REMOTE_FILE: &str = "docker/docker-compose.remote.yml";
pub const DOCKERFILE_REMOTE: &str = "docker/Dockerfile.remote";
}
pub mod env {
pub const EXAMPLE: &str = ".env.example";
pub const FILE: &str = ".env";
}
pub mod meta {
pub const README: &str = "README.md";
pub const GITIGNORE: &str = ".gitignore";
pub const PACKAGE_JSON: &str = "package.json";
pub const REQUIREMENTS_TXT: &str = "requirements.txt";
pub const LS_LINT_CONFIG: &str = ".ls-lint.yml";
}
pub mod rust {
pub const CARGO_TOML: &str = "Cargo.toml";
pub const CARGO_LOCK: &str = "Cargo.lock";
pub const MAIN_RS: &str = "src/main.rs";
pub const LIB_RS: &str = "src/lib.rs";
pub const BUILD_RS: &str = "build.rs";
pub const RUSTFMT_TOML: &str = "rustfmt.toml";
}
pub mod model {
pub const ONNX_FILE: &str = "model.onnx";
pub const LABELS_FILE: &str = "labels.txt";
pub const CONFIG_FILE: &str = "config.json";
}
pub mod user {
use std::path::PathBuf;
pub const MECHA10_DIR: &str = mecha10_core::fs_utils::MECHA10_DIR;
pub const CREDENTIALS_FILE: &str = ".mecha10/credentials.json";
pub const TEMPLATES_DIR: &str = ".mecha10/templates";
pub const BIN_DIR: &str = ".mecha10/bin";
pub fn mecha10_dir() -> PathBuf {
dirs::home_dir().unwrap_or_else(|| PathBuf::from(".")).join(MECHA10_DIR)
}
pub fn credentials_file() -> PathBuf {
mecha10_auth::default_credentials_path()
}
pub fn templates_dir() -> PathBuf {
mecha10_dir().join("templates")
}
pub fn bin_dir() -> PathBuf {
mecha10_dir().join("bin")
}
pub fn bin(name: &str) -> PathBuf {
bin_dir().join(name)
}
pub fn cargo_bin(name: &str) -> PathBuf {
mecha10_core::fs_utils::home_subpath(&[".cargo", "bin", name])
}
pub fn local_bin(name: &str) -> PathBuf {
mecha10_core::fs_utils::home_subpath(&[".local", "bin", name])
}
}
pub mod container {
pub const PROJECT_ROOT: &str = "/project";
pub const FRAMEWORK_ROOT: &str = "/mecha10";
pub const APP_ROOT: &str = "/app";
pub const REMOTE_CONFIG: &str = "/app/mecha10.json";
pub fn project_path(relative: &str) -> String {
format!("{}/{}", PROJECT_ROOT, relative)
}
pub fn framework_path(relative: &str) -> String {
format!("{}/{}", FRAMEWORK_ROOT, relative)
}
}
pub mod framework {
pub const PACKAGES_DIR: &str = "packages";
pub const NODES_DIR: &str = "packages/nodes";
pub const DRIVERS_DIR: &str = "packages/drivers";
pub const SIMULATION_DIR: &str = "packages/simulation";
pub const SIMULATION_MODELS_DIR: &str = "packages/simulation/models";
pub const SIMULATION_ENVIRONMENTS_DIR: &str = "packages/simulation/environments";
pub const ROBOT_TASKS_DIR: &str = "packages/simulation/environments/robot-tasks";
pub const ROBOT_TASKS_CATALOG: &str = "packages/simulation/environments/robot-tasks/catalog.json";
pub const TASKRUNNER_DIR: &str = "packages/taskrunner";
pub const ROOT_MARKER_DIR: &str = "packages/core";
pub const RELEASE_BINARY: &str = "target/release/mecha10";
pub const DEBUG_BINARY: &str = "target/debug/mecha10";
pub fn node_config(node_name: &str) -> String {
format!("packages/nodes/{}/configs/config.json", node_name)
}
}
pub mod urls {
pub const MECHA10_API_URL: &str = "https://mecha.industries/api";
pub fn mecha10_api_base_url() -> String {
std::env::var("MECHA10_API_URL")
.unwrap_or_else(|_| MECHA10_API_URL.to_string())
.trim_end_matches('/')
.to_string()
}
pub const AUTH_URL: &str = "https://mecha.industries/api/auth";
}
pub fn target_path(profile: &str, binary: &str) -> String {
format!("target/{}/{}", profile, binary)
}
pub fn target_path_with_triple(target: Option<&str>, profile: &str) -> String {
match target {
Some(t) => format!("target/{}/{}", t, profile),
None => format!("target/{}", profile),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn credentials_file_matches_mecha10_auth_source_of_truth() {
assert_eq!(user::credentials_file(), mecha10_auth::default_credentials_path());
}
#[test]
fn simulation_project_dirs_share_the_simulation_root() {
assert_eq!(project::SIMULATION_MODELS_DIR, "simulation/models");
assert_eq!(project::SIMULATION_ENVIRONMENTS_DIR, "simulation/environments");
assert_eq!(project::SIMULATION_TASKS_DIR, "simulation/tasks");
for dir in [
project::SIMULATION_MODELS_DIR,
project::SIMULATION_ENVIRONMENTS_DIR,
project::SIMULATION_TASKS_DIR,
] {
assert!(dir.starts_with(&format!("{}/", project::SIMULATION_DIR)));
}
}
#[test]
fn test_config_paths() {
assert_eq!(
config::framework_node("object-detector"),
"configs/nodes/@mecha10/object-detector/config.json"
);
assert_eq!(config::project_node("camera"), "configs/nodes/camera/config.json");
}
#[test]
fn test_framework_node_dir() {
assert_eq!(config::framework_node_dir("speaker"), "configs/nodes/@mecha10/speaker");
}
#[test]
fn test_node_config_candidates_order() {
assert_eq!(
config::node_config_candidates("teleop"),
[
"configs/nodes/@mecha10/teleop/config.json".to_string(),
"configs/nodes/teleop/config.json".to_string(),
]
);
}
#[test]
fn test_behavior_config_paths() {
assert_eq!(
config::framework_behavior("idle_wander"),
"configs/behaviors/@mecha10/idle_wander/config.json"
);
assert_eq!(
config::project_behavior("idle_wander"),
"configs/behaviors/idle_wander/config.json"
);
}
#[test]
fn test_behavior_config_candidates_order() {
assert_eq!(
config::behavior_config_candidates("idle_wander"),
[
"configs/behaviors/idle_wander/config.json".to_string(),
"configs/behaviors/@mecha10/idle_wander/config.json".to_string(),
]
);
}
#[test]
fn test_target_path() {
assert_eq!(target_path("release", "my-node"), "target/release/my-node");
assert_eq!(
target_path_with_triple(Some("aarch64-unknown-linux-gnu"), "release"),
"target/aarch64-unknown-linux-gnu/release"
);
assert_eq!(target_path_with_triple(None, "debug"), "target/debug");
}
#[test]
fn test_container_paths() {
assert_eq!(
container::project_path("configs/test.json"),
"/project/configs/test.json"
);
assert_eq!(container::framework_path("packages/core"), "/mecha10/packages/core");
}
#[test]
fn test_mecha10_api_base_url_default() {
let _guard = ENV_MUTEX.lock().unwrap();
std::env::remove_var("MECHA10_API_URL");
assert_eq!(urls::mecha10_api_base_url(), "https://mecha.industries/api");
}
#[test]
fn test_mecha10_api_base_url_env_override() {
let _guard = ENV_MUTEX.lock().unwrap();
std::env::set_var("MECHA10_API_URL", "http://localhost:4000/api/");
assert_eq!(urls::mecha10_api_base_url(), "http://localhost:4000/api");
std::env::remove_var("MECHA10_API_URL");
}
static ENV_MUTEX: std::sync::Mutex<()> = std::sync::Mutex::new(());
}