Hone logo
Hone
Problems

Rust Workspace Manager

Imagine you're building a command-line tool that helps developers manage their Rust projects. A crucial feature of such a tool is the ability to create new Rust projects, often referred to as "workspaces" in Rust's terminology (though here we'll use it to mean a single project directory). This challenge will have you create a Rust program that can generate a basic Rust project directory structure.

Problem Description

Your task is to create a Rust program that, when given a project name, generates a directory structure for a new Rust project. This structure should include the essential files and directories needed for a minimal, runnable Rust project.

Key Requirements:

  1. Project Directory Creation: The program must create a new directory with the name provided as input.
  2. src Directory: Inside the project directory, it must create a src subdirectory.
  3. main.rs File: Inside the src directory, it must create a main.rs file. This file should contain a simple "Hello, world!" program.
  4. Cargo.toml File: At the root of the project directory, it must create a Cargo.toml file. This file should be a valid, minimal Cargo.toml with basic project information.
  5. Error Handling: The program should gracefully handle potential errors, such as:
    • If the directory already exists.
    • If there are issues creating directories or files.
    • If an invalid project name is provided (e.g., contains disallowed characters).

Expected Behavior:

When the program is run with a valid project name, it should output a success message indicating the project has been created. If an error occurs, it should output an informative error message.

Edge Cases:

  • Project name with spaces or special characters: While Rust package names have restrictions, for this challenge, we'll assume a basic validation for common disallowed characters and spaces.
  • Permissions issues: The program should report if it lacks the necessary permissions to create directories or files.

Examples

Example 1:

Input: my_new_project

Output:

Successfully created Rust workspace: my_new_project

File System Structure Created:

my_new_project/
├── Cargo.toml
└── src/
    └── main.rs

Explanation: A directory named my_new_project is created. Inside it, a Cargo.toml and a src directory are created. The src directory contains main.rs with a "Hello, world!" program.

Example 2:

Input: another_project

Output:

Successfully created Rust workspace: another_project

File System Structure Created:

another_project/
├── Cargo.toml
└── src/
    └── main.rs

Explanation: Similar to Example 1, a new project directory another_project is generated with the standard Rust project structure.

Example 3: (Error Case)

Input: existing_project (assuming a directory named existing_project already exists)

Output:

Error: Directory 'existing_project' already exists.

Explanation: The program detects that the target directory already exists and reports an error without making any changes.

Example 4: (Error Case - Invalid Name)

Input: my project

Output:

Error: Invalid project name 'my project'. Project names cannot contain spaces or special characters.

Explanation: The program validates the project name and rejects it due to the presence of a space.

Constraints

  • The project name must be a valid Rust identifier (alphanumeric characters and underscores, starting with an alphabetic character). For simplicity in this challenge, we will disallow spaces and common special characters like !@#$%^&*()+= etc.
  • The program should use Rust's standard library for file system operations.
  • The generated main.rs should contain fn main() { println!("Hello, world!"); }.
  • The generated Cargo.toml should minimally contain:
    [package]
    name = "PROJECT_NAME"
    version = "0.1.0"
    edition = "2021"
    
    [dependencies]
    
    (where PROJECT_NAME is replaced by the actual project name).

Notes

  • You'll need to explore Rust's std::fs module for creating directories and files.
  • Consider how you will handle multiple potential error conditions and provide clear feedback to the user.
  • The std::path::PathBuf type is useful for constructing file paths.
  • When creating the Cargo.toml file, you'll need to perform string formatting to insert the project name.
Loading editor...
rust