├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .github └── workflows │ ├── lint.yml │ ├── release.yml │ ├── rustfmt.yml │ └── tests.yml ├── .gitignore ├── Cargo.toml ├── LICENSE ├── Makefile ├── README.md └── src ├── lib.rs └── main.rs /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/devcontainers/rust:0-1-bullseye 2 | 3 | # Include lld linker to improve build times either by using environment variable 4 | # RUSTFLAGS="-C link-arg=-fuse-ld=lld" or with Cargo's configuration file (i.e see .cargo/config.toml). 5 | RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 6 | && apt-get -y install clang lld \ 7 | && apt-get autoremove -y && apt-get clean -y 8 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: 2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/rust 3 | { 4 | "name": "Rust", 5 | "build": { 6 | "dockerfile": "Dockerfile", 7 | "args": { 8 | // Use the VARIANT arg to pick a Debian OS version: buster, bullseye 9 | // Use bullseye when on local on arm64/Apple Silicon. 10 | "VARIANT": "buster" 11 | } 12 | }, 13 | "runArgs": [ 14 | "--cap-add=SYS_PTRACE", 15 | "--security-opt", 16 | "seccomp=unconfined" 17 | ], 18 | 19 | // Configure tool-specific properties. 20 | "customizations": { 21 | // Configure properties specific to VS Code. 22 | "vscode": { 23 | // Set *default* container specific settings.json values on container create. 24 | "settings": { 25 | "lldb.executable": "/usr/bin/lldb", 26 | // VS Code don't watch files under ./target 27 | "files.watcherExclude": { 28 | "**/target/**": true 29 | }, 30 | "rust-analyzer.checkOnSave.command": "clippy" 31 | }, 32 | 33 | // Add the IDs of extensions you want installed when the container is created. 34 | "extensions": [ 35 | "rust-lang.rust-analyzer", 36 | "GitHub.copilot-nightly", 37 | "GitHub.copilot-labs" 38 | ] 39 | } 40 | }, 41 | 42 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 43 | // "forwardPorts": [], 44 | 45 | // Use 'postCreateCommand' to run commands after the container is created. 46 | "postCreateCommand": "./setup.sh", 47 | 48 | // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. 49 | "remoteUser": "vscode" 50 | } 51 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Clippy 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v1 11 | - uses: actions-rs/toolchain@v1 12 | with: 13 | toolchain: stable 14 | profile: minimal 15 | components: clippy, rustfmt 16 | override: true 17 | - name: Run clippy 18 | run: make lint 19 | 20 | 21 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Build binary release 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v1 11 | - uses: actions-rs/toolchain@v1 12 | with: 13 | toolchain: stable 14 | profile: minimal 15 | components: clippy, rustfmt 16 | override: true 17 | - name: Run clippy 18 | run: make build-release 19 | -------------------------------------------------------------------------------- /.github/workflows/rustfmt.yml: -------------------------------------------------------------------------------- 1 | name: Rustfmt 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v1 11 | - uses: actions-rs/toolchain@v1 12 | with: 13 | toolchain: stable 14 | profile: minimal 15 | components: clippy, rustfmt 16 | override: true 17 | - name: Run rustfmt 18 | run: make format-check -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v1 11 | - uses: actions-rs/toolchain@v1 12 | with: 13 | toolchain: stable 14 | profile: minimal 15 | components: clippy, rustfmt 16 | override: true 17 | - name: Run clippy 18 | run: make test 19 | 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 6 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 7 | Cargo.lock 8 | 9 | # These are backup files generated by rustfmt 10 | **/*.rs.bk 11 | 12 | 13 | # Added by cargo 14 | 15 | /target 16 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = {version="4.0.32", features=["derive"]} -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | rust-version: 2 | @echo "Rust command-line utility versions:" 3 | rustc --version #rust compiler 4 | cargo --version #rust package manager 5 | rustfmt --version #rust code formatter 6 | rustup --version #rust toolchain manager 7 | clippy-driver --version #rust linter 8 | 9 | format: 10 | cargo fmt --quiet 11 | 12 | lint: 13 | cargo clippy --quiet 14 | 15 | test: 16 | cargo test --quiet 17 | 18 | run: 19 | cargo run 20 | 21 | release: 22 | cargo build --release 23 | 24 | all: format lint test run 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rust-new-project-template 2 | 3 | All Rust projects can follow this pattern: 4 | 5 | 1. Create a new repo using Rust New Project Template: https://github.com/noahgift/rust-new-project-template 6 | 2. Create a new Codespaces and use it 7 | 3. Use `main.rs` to call handle CLI and use `lib.rs` to handle logic and import `clap` in `Cargo.toml` as shown in this project. 8 | 4. Use `cargo init --name 'hello' or whatever you want to call your project. 9 | 5. Put your "ideas" in as comments in rust to seed GitHub Copilot, i.e //build add function 10 | 6. Run `make format` i.e. `cargo format` 11 | 7. Run `make lint` i.e. `cargo clippy --quiet` 12 | 8. Run project: `cargo run -- --help` 13 | 9. Push your changes to allow GitHub Actions to: `format` check, `lint` check, and other actions like binary deploy. 14 | 15 | 16 | This pattern is a new emerging pattern and is ideal for systems programming in Rust. 17 | 18 | ![1 1-prompt-engineering](https://user-images.githubusercontent.com/58792/213335664-f459e6ac-018a-4ccf-9563-bbe6d49d72d1.png) 19 | 20 | 21 | ### Reproduce 22 | A good starting point for a new Rust project 23 | 24 | To run: `cargo run -- marco --name "Marco"` 25 | Be careful to use the NAME of the project in the `Cargo.toml` to call `lib.rs` as in: 26 | 27 | ``` 28 | [package] 29 | name = "hello" 30 | ``` 31 | 32 | For example, see the name `hello` is invoked alongside `marco_polo` which is in `lib.rs`. 33 | 34 | ```rust 35 | fn main() { 36 | let args = Cli::parse(); 37 | match args.command { 38 | Some(Commands::Marco { name }) => { 39 | println!("{}", hello::marco_polo(&name)); 40 | } 41 | None => println!("No command was used"), 42 | } 43 | } 44 | ``` 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | ## References 53 | 54 | * [rust-cli-template](https://github.com/kbknapp/rust-cli-template) 55 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | /* A Marco Polo game. */ 2 | 3 | /* Accepts a string with a name. 4 | If the name is "Marco", returns "Polo". 5 | If the name is "any other value", it returns "Marco". 6 | */ 7 | pub fn marco_polo(name: &str) -> String { 8 | if name == "Marco" { 9 | "Polo".to_string() 10 | } else { 11 | "Marco".to_string() 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | //A command-line tool that plays Marco Polo 2 | use clap::Parser; 3 | 4 | #[derive(Parser)] 5 | #[clap(version = "1.0", author = "Noah Gift", about = "A Marco Polo game.")] 6 | struct Cli { 7 | #[clap(subcommand)] 8 | command: Option, 9 | } 10 | 11 | #[derive(Parser)] 12 | enum Commands { 13 | #[clap(version = "1.0", author = "Noah Gift", about = "A Marco Polo game.")] 14 | Marco { 15 | #[clap(short, long)] 16 | name: String, 17 | }, 18 | } 19 | 20 | // This is the main function 21 | // hello::marco_polo(&name) 22 | fn main() { 23 | let args = Cli::parse(); 24 | match args.command { 25 | Some(Commands::Marco { name }) => { 26 | println!("{}", hello::marco_polo(&name)); 27 | } 28 | None => println!("No command was used"), 29 | } 30 | } 31 | --------------------------------------------------------------------------------