[{"data":1,"prerenderedAt":722},["ShallowReactive",2],{"/en-us/blog/learning-rust-with-a-little-help-from-ai-code-suggestions-getting-started/":3,"navigation-en-us":38,"banner-en-us":467,"footer-en-us":484,"Michael Friedrich":694,"next-steps-en-us":707},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":8,"content":16,"config":28,"_id":31,"_type":32,"title":33,"_source":34,"_file":35,"_stem":36,"_extension":37},"/en-us/blog/learning-rust-with-a-little-help-from-ai-code-suggestions-getting-started","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"Learning Rust with a little help from AI","Use this guided tutorial, along with GitLab Duo Code Suggestions, to learn a new programming language.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663918/Blog/Hero%20Images/aipower.jpg","https://about.gitlab.com/blog/learning-rust-with-a-little-help-from-ai-code-suggestions-getting-started","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Learning Rust with a little help from AI\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Michael Friedrich\"}],\n        \"datePublished\": \"2023-08-10\",\n      }",{"title":9,"description":10,"authors":17,"heroImage":11,"date":19,"body":20,"category":21,"tags":22},[18],"Michael Friedrich","2023-08-10","Learning a new programming language can help broaden your software\ndevelopment expertise, open career opportunities, or create fun challenges.\nHowever, it can be difficult to decide on one specific approach to learning\na new language. Artificial intelligence (AI) can help. In this tutorial,\nyou'll learn how to leverage AI-powered GitLab Duo Code Suggestions for a\nguided experience in learning the Rust programming language.\n\n\n- [Preparations](#preparations)\n  - [VS Code](#vs-code)\n  - [Code Suggestions](#code-suggestions)\n- [Learning a new programming language:\nRust](#learning-a-new-programming-language-rust)\n    - [Development environment for Rust](#development-environment-for-rust)\n    - [Hello, World](#hello-world)\n- [Cargo: Bringing structure into Rust](#cargo-bringing-structure-into-rust)\n\n- [Automation: Configure CI/CD pipeline for\nRust](#automation-configure-cicd-pipeline-for-rust)\n\n- [Continue learning Rust](#continue-learning-rust)\n    - [Define variables and print them](#define-variables-and-print-them)\n    - [Explore variable types](#explore-variable-types)\n    - [Flow control: Conditions and loops](#flow-control-conditions-and-loops)\n    - [Functions](#functions)\n    - [Testing](#testing)\n- [What is next](#what-is-next)\n    - [Async learning exercises](#async-learning-exercises)\n    - [Share your feedback](#share-your-feedback)\n\n## Preparations \n\nChoose your [preferred and supported\nIDE](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#enable-code-suggestions-in-other-ides-and-editors),\nand follow the documentation to enable code suggestions for [GitLab.com\nSaaS](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#enable-code-suggestions-on-gitlab-saas)\nor [GitLab self-managed\ninstances](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#enable-code-suggestions-on-self-managed-gitlab).\n\n\nProgramming languages can require an install of the language interpreter\ncommand-line tools or compilers that generate binaries from source code to\nbuild and run the application.\n\n\nTip: You can also use [GitLab Remote Development\nworkspaces](/blog/quick-start-guide-for-gitlab-workspaces/) to\ncreate your own cloud development environments, instead of local development\nenvironments. This blog post focuses on using VS Code and the GitLab Web\nIDE. \n\n\n### VS Code\n\nOn macOS, you can [install VS Code](https://code.visualstudio.com/download)\nas a Homebrew cask or manually download and install it. \n\n\n```shell\n\nbrew install --cask visual-studio-code \n\n```\n\n\nNavigate to the `Extensions` menu and search for `gitlab workflow`. Install\nthe [GitLab workflow extension for VS\nCode](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow). \n\n\nTip: VS Code will also detect the programming languages, and offer to\ninstall additional plugins for syntax highlighting and development\nexperience. \n\n\n### Code Suggestions\n\nIt can help to familiarize yourself with suggestions before actually\nverifying the suggestions. GitLab Code Suggestions are provided as you type,\nso you do not need use specific keyboard shortcuts. To accept a code\nsuggestion, press the `tab` key. Also note that writing new code works more\nreliably than refactoring existing code. AI is non-deterministic, which\nmeans that the same suggestion may not be repeated after deleting the code\nsuggestion. While Code Suggestions is in Beta, we are working on improving\nthe accuracy of generated content overall. Please review the [known\nlimitations](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#known-limitations),\nas this could affect your learning experience. \n\n\n## Learning a new programming language: Rust \n\nNow, let's dig into learning Rust, which is one of the [supported languages\nin Code\nSuggestions](https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html#supported-languages). \n\n\n[Rust by Example](https://doc.rust-lang.org/rust-by-example/) provides a\ngreat tutorial for beginners, together with the official [Rust\nbook](https://doc.rust-lang.org/book/). The [Hands-on Rust\nbook](https://hands-on-rust.com/) shows how to build a 2D game as a more\npractical approach. More examples are shared in [this Rust book\nlist](https://github.com/sger/RustBooks). \n\n\nBefore diving into the source code, make sure to set up your development\nenvironment.\n\n\n### Development environment for Rust\n\n1) Create a new project `learn-rust-ai` in GitLab, and clone the project\ninto your development environment. All code snippets are available in [this\n\"Learn Rust with AI\"\nproject](https://gitlab.com/gitlab-de/use-cases/ai/learn-with-ai/learn-rust-ai).\n\n\n```shell\n\ngit clone https://gitlab.com/NAMESPACE/learn-rust-ai.git\n\n\ncd learn-rust-ai\n\n\ngit status\n\n```\n\n\n2) Install Rust and the build toolchain. Fortunately, this is\nstraightforward [following the Rust install\ndocumentation](https://www.rust-lang.org/tools/install).\n\n\nTip for using the generic installer: Download the script and run it after\nreview. \n\n\n```\n\n# Download and print the script before running it\n\ncurl -Lvs https://sh.rustup.rs -o rustup-init.sh\n\n\n# Run the Rust installer script\n\nsh rustup-init.sh \n\n```\n\n\nExample on macOS using Homebrew:\n\n\n```\n\nbrew install rust\n\n```\n\n\n1) Optional: Install the [rust-analyzer VS Code\nextension](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer).\n\n\n2) Each exercise will invite you to compile the code with the [`rustc`\ncommand](https://doc.rust-lang.org/rustc/what-is-rustc.html), and later\nusing [`cargo` as build tool and package\nmanager](https://doc.rust-lang.org/cargo/index.html).\n\n\nYou are all set to learn Rust! \n\n\n### Hello, World\n\nWe will start with [Rust by\nExample](https://doc.rust-lang.org/rust-by-example/), and follow the [Hello,\nWorld exercise](https://doc.rust-lang.org/rust-by-example/hello.html).\n\n\nCreate a new file `hello.rs` in the root directory of the project and start\nwith a comment saying `// Hello world`. Next, start writing the `main`\nfunction, and verify the code suggestion.\n\n\n![VS Code hello.rs Rust code suggestion, asking to\naccept](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_hello_world_suggested.png){:\n.shadow}\n\n\nAccept the suggestion by pressing the `tab` key and save the file (keyboard\nshortcut: cmd s). \n\n\n```\n\n// Hello world\n\n\nfn main() {\n    println!(\"Hello, world!\");\n}\n\n```\n\n\n![VS Code hello.rs Rust code suggestion,\naccepted](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_hello_world_accepted.png){:\n.shadow}\n\n\nCommit the change to the Git repository. In VS Code, use the keyboard\nshortcut `ctrl shift G`, add a commit message, and hit `cmd enter` to\nsubmit. \n\n\nUse the command palette (`cmd shift p`) and search for `create terminal` to\nopen a new terminal. \n\n\nBuild and run the code.\n\n\n```shell\n\nrustc hello.rs\n\n\n./hello\n\n```\n\n\n![hello.rs Rust code suggestion, accepted, compiled,\nrun](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_hello_world_cli_build.png){:\n.shadow}\n\n\nTip: Adding [code comments in Rust\n(`//`)](https://doc.rust-lang.org/reference/comments.html) before you start\nwriting a function or algorithm will help Code Suggestions with more context\nto provide better suggestions. In the example above, we did that with `//\nHello world`, and will continue doing so in the next exercises. \n\n\n## Cargo: Bringing structure into Rust\n\n[Cargo](https://doc.rust-lang.org/rust-by-example/cargo.html) is the\nofficial Rust package management tool. It is more than that - you can run\nbuild and test commands because Cargo understands them as well. \n\n\nYou can initialize a new Cargo configuration in the current directory tree\nwith the following command:\n\n\n```shell\n\ncargo init\n\n```\n\n\nThe directory tree invites you to add the source code into the `src/`\ndirectory, while `Cargo.toml` manages the dependencies and used compiler\nversions. The `.gitignore` file is also added including best practices. \n\n\n```shell\n\ntree\n\n.\n\n├── Cargo.toml\n\n├── README.md\n\n├── hello\n\n├── hello.rs\n\n└── src\n    └── main.rs\n```\n\n\nTry building the code and running it using `cargo`.\n\n\n```shell\n\ncargo build\n\n\ncargo run\n\n```\n\n\nCommit all changes and push them to your GitLab project.\n\n\n```shell\n\ngit commit -avm \"Initialize Cargo\"\n\n\ngit push\n\n```\n\n\nAfter exploring Cargo, let's make sure that our code is continuously tested\nwhile learning Rust. The next section explains how to set up [GitLab\nCI/CD](https://about.gitlab.com/topics/ci-cd/) for Rust. \n\n\n## Automation: Configure CI/CD pipeline for Rust\n\nThe [CI/CD pipeline](https://docs.gitlab.com/ee/ci/) should run two jobs in\ntwo stages: Build and test the code. The default container\n[image](https://docs.gitlab.com/ee/ci/yaml/#image), `rust:latest`, works in\nthe first iteration. In order to save resources, the CI/CD configuration\nalso supports [caching](https://docs.gitlab.com/ee/ci/caching/) for\ndownloaded dependencies and build objects. The `CARGO_HOME` variable is set\nto the CI/CD job home directory to ensure everything gets appropriately\ncached.\n\n\n```yaml\n\nstages:\n  - build\n  - test \n\ndefault:\n  image: rust:latest\n  cache:\n    key: ${CI_COMMIT_REF_SLUG}\n    paths:                      \n      - .cargo/bin\n      - .cargo/registry/index\n      - .cargo/registry/cache\n      - target/debug/deps\n      - target/debug/build\n    policy: pull-push\n\n# Cargo data needs to be in the project directory to be cached. \n\nvariables:\n  CARGO_HOME: ${CI_PROJECT_DIR}/.cargo      \n```\n\n\nThe CI/CD jobs inherit the\n[`default`](https://docs.gitlab.com/ee/ci/yaml/#default) values, and specify\nthe cargo commands in the [`script`\nsection](https://docs.gitlab.com/ee/ci/yaml/#script).\n\n\n```yaml\n\nbuild-latest:\n  stage: build\n  script:\n    - cargo build --verbose\n\ntest-latest:\n  stage: build\n  script:\n    - cargo test --verbose\n```\n\n\nYou can see an example in [this\nMR](https://gitlab.com/gitlab-de/use-cases/ai/learn-with-ai/learn-rust-ai/-/merge_requests/1/diffs).\n\n\n## Continue learning Rust \n\nMake sure to add new source code into the `src/` directory. \n\n\n### Define variables and print them\n\nPractice adding a few more\n[print](https://doc.rust-lang.org/rust-by-example/hello/print.html)\nstatements into `src/main.rs`, and then build and run the code again.\n\n\n1) Define a variable called `name` and assign your name as string value.\n\n\n2) Print the name, including a string prefix saying `Hello, `. \n\n\n![VS Code main.rs Rust code suggestion, first step in\nprint](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_print_variable_first.png){:\n.shadow}\n\n\n![VS Code main.rs Rust code suggestion, second step in\nprint](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_print_variable_second.png){:\n.shadow}\n\n\n1) Open a new terminal in VS Code using the command palette (keyboard\nshortcut `cmd + shift + p`) and search for `terminal`.\n\n\n2) Build and run the code with the `cargo build` and `cargo run` commands. \n\n\n![VS Code terminal with cargo build and run\noutput](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_print_variable_cargo_build_run_terminal.png){:\n.shadow}\n\n\nAn example solution can be found\n[here](https://gitlab.com/gitlab-de/use-cases/ai/learn-with-ai/learn-rust-ai/-/blob/main/solutions/variable_print.rs). \n\n\n### Explore variable types \n\nDefine different variable value types\n([primitives](https://doc.rust-lang.org/rust-by-example/primitives.html))\nand embed them into the `print` statements. Maybe they feel familiar with\nother programming languages?\n\n\nTip: Use code comments to see which code suggestions can be useful to learn.\nStart with typing `// Integer addition` and see what code suggestions you\ncan add.\n\n\n![VS Code main.rs Rust code suggestion, primitive types with literals and\nexpressions](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_primitive_types_literals_operators.png)\n\n\nExperiment with GitLab Duo Code Suggestions. The shown examples are\nnon-deterministic, but you may be able to add additions, subscriptions,\nmultiplications, etc., and the corresponding `println` statements just by\naccepting code suggestions and continuing the flow with `enter` or\ncompleting the code statements. This workflow can create a chain of code\nsuggestions that can help you learn the Rust language. \n\n\n![Literals and expressions, first\nsuggestion](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_literals_expressions_01.png){:\n.shadow}\n\n![Literals and expressions, second\nsuggestion](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_literals_expressions_02.png){:\n.shadow}\n\n![Literals and expressions, third\nsuggestion](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_literals_expressions_03.png){:\n.shadow}\n\n\nAn example solution can be found\n[here](https://gitlab.com/gitlab-de/use-cases/ai/learn-with-ai/learn-rust-ai/-/blob/main/solutions/literals_expressions.rs). \n\n\nThe code suggestions are not perfect. Sometimes there are errors that\nrequire you to fix the problems. When writing this blog post, I had to fix\ntwo missing semicolons at the end of the code lines. The great thing about\nthe Rust compiler is that the error messages tell you exactly where the\nproblem happens with suggestions to fix them. Code Suggestions and the\nRust-provided build chain make writing Rust code more efficient. \n\n\n```rust\n\nprintln!(\"Hello, {}!\", name)\n\n\n// Integer subtraction\n\nlet y = 9 - 4\n\n```\n\n\n![Terminal build, errors, Rust compiler\nhelp](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_terminal_errors_rust_help.png){:\n.shadow}\n\n\nYou can try to provoke the same error by removing a semicolon at the end of\na statement and then running `cargo build` in the terminal again. The Rust\ncompiler will also warn you about unused variables to help with better code\nquality. The screenshot shows warnings for variable definitions, and also a\nCLI command to fix them. \n\n\n![Terminal build, warnings, Rust compiler\nhelp](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_terminal_warnings_rust_help.png){:\n.shadow}\n\n\n### Flow control: Conditions and loops \n\nNext, let's focus on [flow\ncontrol](https://doc.rust-lang.org/rust-by-example/flow_control.html) with\nconditions, loops, etc., and how to implement them.\n\n\n1) Start typing `// Flow control` and see which suggestions are provided.\n\n\n2) Experiment with the code, and continue defining a boolean variable `v`\nwhich is set to true. \n\n\n```rust\n  // Flow control\n  let v = true;\n\n```\n\n\n![Conditions, boolean\nvariable](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_flow_control_conditions_01.png){:\n.shadow}\n\n![Conditions, boolean variable, if\ncondition](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_flow_control_conditions_02.png){:\n.shadow}\n\n\n1) Start typing `// Loops` and experiment with the code suggestions. \n\n\nLet's assume the loop looks the like following snippet. It does not have a\nloop counter which gets printed on every loop execution.\n\n\n```rust\n\n// Loops\n\nlet mut count = 0;\n\n\nloop {\n    count += 1;\n\n    if count == 10 {\n        break;\n    }\n}\n\n```\n\n\n2) Start typing `println!` and see which code suggestions are provided, for\nexample `println!(\"Count: {}\", count);`. \n\n\n![Loops, loop counter print\nsuggestion](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_flow_control_loops_print_counter.png)\n\n\n3) Apply the suggestions, and execute `cargo build && cargo run` on the\nterminal again. \n\n\nLet's learn more: Rust supports different loop types, for example [while\nloops](https://doc.rust-lang.org/rust-by-example/flow_control/while.html),\n[for\nloops](https://doc.rust-lang.org/rust-by-example/flow_control/for.html),\netc. \n\n\n1) Type `// While loop` and verify the code suggestions. Repeat the same for\n`// For loop`.\n\n\n```rust\n\n// While loops\n\nlet mut count = 0;\n\n\nwhile count \u003C 10 {\n    count += 1;\n    println!(\"Count: {}\", count);\n}\n\n\n// For loops\n\nlet a = [10, 2, 3, 4, 5];\n\n\nfor element in a {\n    println!(\"Element: {}\", element);\n}\n\n```\n\n\nThere is more to learn with loops and conditions: Iterate over arrays,\nlists, maps, slices. Practice with writing comments for `// Maps and sets`\nand `// Vectors and strings`. \n\n\n![Vectors,\nstrings](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_flow_control_vectors_strings.png){:\n.shadow}\n\n\n```rust\n  // Maps and sets\n  let mut scores = HashMap::new();\n\n  scores.insert(String::from(\"Blue\"), 10);\n  scores.insert(String::from(\"Yellow\"), 50);\n\n  for (key, value ) in &scores {\n      println!(\"{}: {}\", key, value);\n  }\n\n  // Vectors and strings\n  let mut v = Vec::new();\n\n  v.push(1);\n  v.push(2);\n\n  for element in &v {\n      println!(\"Element: {}\", element);\n  }  \n```\n\n\nThis snippet will fail because the `HashMap` type needs to be imported from\n`std::collections::HashMap`. Add the following line on top before the main\nfunction definition: \n\n\n```rust\n\nuse std::collections::HashMap;\n\n``` \n\n\n2) Build and run the code with `cargo build && cargo run`. \n\n\nAn example solution is provided\n[here](https://gitlab.com/gitlab-de/use-cases/ai/learn-with-ai/learn-rust-ai/-/blob/main/solutions/flow_control.rs).\n\n\n**Async exercise**: \n\n\n1) Modify the input values for the different data types, and build and run\nthe code again.\n\n\n2) Add a condition into the loops that print the items only when a specific\ncondition is met (for example, the number is odd or even). \n\n\n### Functions \n\n\n[Functions](https://doc.rust-lang.org/rust-by-example/fn.html) help increase\ncode readability and testability with unit tests. Practice creating\nfunctions with the following steps: \n\n\n1) Two functions `isEven` and `isOdd` to evaluate whether a number is even\nor odd.\n\n\n```rust\n\nfn isEven(x: i32) -> bool {\n    x % 2 == 0\n}\n\n\nfn isOdd(x: i32) -> bool {\n    x % 2 != 0\n}\n\n```\n\n\n2) `isPrime` function to check whether a given integer value is a prime\nnumber.\n\n\n```rust\n\nfn isPrime(x: i32) -> bool {\n    let mut i = 2;\n\n    while i * i \u003C= x {\n        if x % i == 0 {\n            return false;\n        } else {\n            i += 1;\n        }\n    } \n\n    return true\n}\n\n```\n\n\n3) Create an array of integer values, loop over it, and call the functions.\nLet GitLab Code Suggestions guide you with the implementation by starting to\ntype the if conditions followed by the function name. \n\n\n```rust\n  // Functions\n  let mut integers = vec![1, 2, 3, 4, 5];\n\n  for i in integers.iter() {\n\n      if (isEven(i)) {\n          println!(\"{} is even\", i);\n      }\n\n      if (isOdd(i)) { \n          println!(\"{} is odd\", i);\n      }\n\n      if (isPrime(i)) { \n          println!(\"{} is prime\", i);\n      }\n\n      println!(\"{}\", i);\n  }\n```\n\n\nNote that passing a reference value to a function may result in an error\nfrom the Rust compiler. Follow the suggestions and build the code again. \n\n\n```shell\n\n$ cargo build && cargo run \n\n\nerror[E0308]: mismatched types\n   --> src/main.rs:112:21\n    |\n112 |         if (isPrime(i)) { \n    |             ------- ^ expected `i32`, found `&{integer}`\n    |             |\n    |             arguments to this function are incorrect\n    |    \nnote: function defined here\n   --> src/main.rs:136:4\n    |\n136 | fn isPrime(x: i32) -> bool {\n    |    ^^^^^^^ ------\nhelp: consider dereferencing the borrow\n    |\n112 |         if (isPrime(*i)) { \n    |                     +\n```\n\n\nAn example solution is provided\n[here](https://gitlab.com/gitlab-de/use-cases/ai/learn-with-ai/learn-rust-ai/-/blob/main/solutions/functions.rs).\n\n\n**Async exercise**: Create a function `containsString` and test it with an\narray of string values, and a string to search for, in a loop. The\nscreenshot shows a potential implementation. \n\n\n![containsString function, and vector with string elements to test,\nsuggesting its usage in the main\nfunction](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_function_implemented_then_suggested_in_main.png){:\n.shadow}\n\n\n### Testing \n\nWhile learning programming, adopt\n[testing](https://doc.rust-lang.org/rust-by-example/testing.html) into your\nprocess. This can be unit tests for functions, documentation testing, and\nintegration testing. Practice with testing the previously created functions\n`isEven`, `isOdd`, and `isPrime`. Starty by typing `mod tests {` followed by\na new line with `use super::*` to implement the example from the [Rust\ndocumentation for unit\ntests](https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html).\n\n\n```rust\n\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_is_even() {\n        assert!(isEven(2)); \n        assert!(!isEven(3));\n    }\n\n    #[test] \n    fn test_is_odd() {\n        assert!(!isOdd(2));\n        assert!(isOdd(3));\n    }\n\n    #[test]\n    fn test_is_prime() { \n        assert!(isPrime(2));\n        assert!(!isPrime(3));\n    }\n}\n\n```\n\n\nRun `cargo test` to run the unit tests. Modify the test values to experiment\nwith the results. \n\n\n```shell\n\ncargo test\n\n```\n\n\n![Function unit tests, cargo test output in the VS Code\nterminal](https://about.gitlab.com/images/blogimages/learn-rust-with-ai-code-suggestions-getting-started/learn_rust_ai_gitlab_code_suggestions_function_unit_tests_terminal_run.png)\n\n\nCreate unit tests that fail, and commit and push the changes to GitLab. The\nCI/CD pipelines will fail in this simulated breakage. The example above\nneeds a fix for the `test_is_prime` test. Commit and push the change to\nverify that the pipeline passes again. \n\n\n```diff\n\n-        assert!(!isPrime(3));\n\n+        assert!(!isPrime(4));\n\n```\n\n\n## What is next \n\nIn an upcoming blog, we will look into advanced learning examples with\nasynchronous operations, services and external API communication in future\nblog posts. Until then, here are a few recommendations for practicing async.\n\n\n### Async learning exercises\n\n- [`std misc`](https://doc.rust-lang.org/rust-by-example/std_misc.html)\nprovides asynchronous operations with threads, channels and file I/O\n\n- Book: [Hands-on Rust: Effective Learning through 2D Game Development and\nPlay](https://pragprog.com/titles/hwrust/hands-on-rust/)\n\n- Tutorial: [Are we game yet?](https://arewegameyet.rs/resources/tutorials/)\n\n- Use case: [Web server with\nrocket.rs](https://rocket.rs/v0.5-rc/guide/quickstart/#running-examples)\n\n\nHere are a few more exercises and ideas for additional learning:\n\n1) The Rust compiler might have created warnings that need to be addressed.\nFollow the instructions from the `cargo build` commands and check the Git\ndiff. \n\n\n```\n\ncargo fix --bin \"learn-rust-ai\"\n\n\ngit diff \n\n```\n\n\n2) [Error handling](https://doc.rust-lang.org/rust-by-example/error.html) is\nrequired when failure is detected, and the caller should know. Some errors\ncan be recovered from within the application, others require program\ntermination. \n\n\n3) The [`std` library](https://doc.rust-lang.org/rust-by-example/std.html)\nextends primitive types and makes programming more efficient. \n\n\n### Share your feedback\n\nWhich programming language are you learning or considering learning? Start a\nnew topic on our [community](/community/) forum or Discord and share your\nexperience.  \n\n\nIf you are using Code Suggestions Beta with [GitLab Duo](/gitlab-duo/)\nalready, please share your thoughts and feedback [in this\nissue](https://gitlab.com/gitlab-org/gitlab/-/issues/405152).\n","ai-ml",[23,24,25,26,27],"DevSecOps","careers","tutorial","workflow","AI/ML",{"slug":29,"featured":6,"template":30},"learning-rust-with-a-little-help-from-ai-code-suggestions-getting-started","BlogPost","content:en-us:blog:learning-rust-with-a-little-help-from-ai-code-suggestions-getting-started.yml","yaml","Learning Rust With A Little Help From Ai Code Suggestions Getting Started","content","en-us/blog/learning-rust-with-a-little-help-from-ai-code-suggestions-getting-started.yml","en-us/blog/learning-rust-with-a-little-help-from-ai-code-suggestions-getting-started","yml",{"_path":39,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"data":41,"_id":463,"_type":32,"title":464,"_source":34,"_file":465,"_stem":466,"_extension":37},"/shared/en-us/main-navigation","en-us",{"logo":42,"freeTrial":47,"sales":52,"login":57,"items":62,"search":394,"minimal":425,"duo":444,"pricingDeployment":453},{"config":43},{"href":44,"dataGaName":45,"dataGaLocation":46},"/","gitlab logo","header",{"text":48,"config":49},"Get free trial",{"href":50,"dataGaName":51,"dataGaLocation":46},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":53,"config":54},"Talk to sales",{"href":55,"dataGaName":56,"dataGaLocation":46},"/sales/","sales",{"text":58,"config":59},"Sign in",{"href":60,"dataGaName":61,"dataGaLocation":46},"https://gitlab.com/users/sign_in/","sign in",[63,107,205,210,315,375],{"text":64,"config":65,"cards":67,"footer":90},"Platform",{"dataNavLevelOne":66},"platform",[68,74,82],{"title":64,"description":69,"link":70},"The most comprehensive AI-powered DevSecOps Platform",{"text":71,"config":72},"Explore our Platform",{"href":73,"dataGaName":66,"dataGaLocation":46},"/platform/",{"title":75,"description":76,"link":77},"GitLab Duo (AI)","Build software faster with AI at every stage of development",{"text":78,"config":79},"Meet GitLab Duo",{"href":80,"dataGaName":81,"dataGaLocation":46},"/gitlab-duo/","gitlab duo ai",{"title":83,"description":84,"link":85},"Why GitLab","10 reasons why Enterprises choose GitLab",{"text":86,"config":87},"Learn more",{"href":88,"dataGaName":89,"dataGaLocation":46},"/why-gitlab/","why gitlab",{"title":91,"items":92},"Get started with",[93,98,103],{"text":94,"config":95},"Platform Engineering",{"href":96,"dataGaName":97,"dataGaLocation":46},"/solutions/platform-engineering/","platform engineering",{"text":99,"config":100},"Developer Experience",{"href":101,"dataGaName":102,"dataGaLocation":46},"/developer-experience/","Developer experience",{"text":104,"config":105},"MLOps",{"href":106,"dataGaName":104,"dataGaLocation":46},"/topics/devops/the-role-of-ai-in-devops/",{"text":108,"left":109,"config":110,"link":112,"lists":116,"footer":187},"Product",true,{"dataNavLevelOne":111},"solutions",{"text":113,"config":114},"View all Solutions",{"href":115,"dataGaName":111,"dataGaLocation":46},"/solutions/",[117,142,166],{"title":118,"description":119,"link":120,"items":125},"Automation","CI/CD and automation to accelerate deployment",{"config":121},{"icon":122,"href":123,"dataGaName":124,"dataGaLocation":46},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[126,130,134,138],{"text":127,"config":128},"CI/CD",{"href":129,"dataGaLocation":46,"dataGaName":127},"/solutions/continuous-integration/",{"text":131,"config":132},"AI-Assisted Development",{"href":80,"dataGaLocation":46,"dataGaName":133},"AI assisted development",{"text":135,"config":136},"Source Code Management",{"href":137,"dataGaLocation":46,"dataGaName":135},"/solutions/source-code-management/",{"text":139,"config":140},"Automated Software Delivery",{"href":123,"dataGaLocation":46,"dataGaName":141},"Automated software delivery",{"title":143,"description":144,"link":145,"items":150},"Security","Deliver code faster without compromising security",{"config":146},{"href":147,"dataGaName":148,"dataGaLocation":46,"icon":149},"/solutions/security-compliance/","security and compliance","ShieldCheckLight",[151,156,161],{"text":152,"config":153},"Application Security Testing",{"href":154,"dataGaName":155,"dataGaLocation":46},"/solutions/application-security-testing/","Application security testing",{"text":157,"config":158},"Software Supply Chain Security",{"href":159,"dataGaLocation":46,"dataGaName":160},"/solutions/supply-chain/","Software supply chain security",{"text":162,"config":163},"Software Compliance",{"href":164,"dataGaName":165,"dataGaLocation":46},"/solutions/software-compliance/","software compliance",{"title":167,"link":168,"items":173},"Measurement",{"config":169},{"icon":170,"href":171,"dataGaName":172,"dataGaLocation":46},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[174,178,182],{"text":175,"config":176},"Visibility & Measurement",{"href":171,"dataGaLocation":46,"dataGaName":177},"Visibility and Measurement",{"text":179,"config":180},"Value Stream Management",{"href":181,"dataGaLocation":46,"dataGaName":179},"/solutions/value-stream-management/",{"text":183,"config":184},"Analytics & Insights",{"href":185,"dataGaLocation":46,"dataGaName":186},"/solutions/analytics-and-insights/","Analytics and insights",{"title":188,"items":189},"GitLab for",[190,195,200],{"text":191,"config":192},"Enterprise",{"href":193,"dataGaLocation":46,"dataGaName":194},"/enterprise/","enterprise",{"text":196,"config":197},"Small Business",{"href":198,"dataGaLocation":46,"dataGaName":199},"/small-business/","small business",{"text":201,"config":202},"Public Sector",{"href":203,"dataGaLocation":46,"dataGaName":204},"/solutions/public-sector/","public sector",{"text":206,"config":207},"Pricing",{"href":208,"dataGaName":209,"dataGaLocation":46,"dataNavLevelOne":209},"/pricing/","pricing",{"text":211,"config":212,"link":214,"lists":218,"feature":302},"Resources",{"dataNavLevelOne":213},"resources",{"text":215,"config":216},"View all resources",{"href":217,"dataGaName":213,"dataGaLocation":46},"/resources/",[219,252,274],{"title":220,"items":221},"Getting started",[222,227,232,237,242,247],{"text":223,"config":224},"Install",{"href":225,"dataGaName":226,"dataGaLocation":46},"/install/","install",{"text":228,"config":229},"Quick start guides",{"href":230,"dataGaName":231,"dataGaLocation":46},"/get-started/","quick setup checklists",{"text":233,"config":234},"Learn",{"href":235,"dataGaLocation":46,"dataGaName":236},"https://university.gitlab.com/","learn",{"text":238,"config":239},"Product documentation",{"href":240,"dataGaName":241,"dataGaLocation":46},"https://docs.gitlab.com/","product documentation",{"text":243,"config":244},"Best practice videos",{"href":245,"dataGaName":246,"dataGaLocation":46},"/getting-started-videos/","best practice videos",{"text":248,"config":249},"Integrations",{"href":250,"dataGaName":251,"dataGaLocation":46},"/integrations/","integrations",{"title":253,"items":254},"Discover",[255,260,264,269],{"text":256,"config":257},"Customer success stories",{"href":258,"dataGaName":259,"dataGaLocation":46},"/customers/","customer success stories",{"text":261,"config":262},"Blog",{"href":263,"dataGaName":5,"dataGaLocation":46},"/blog/",{"text":265,"config":266},"Remote",{"href":267,"dataGaName":268,"dataGaLocation":46},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":270,"config":271},"TeamOps",{"href":272,"dataGaName":273,"dataGaLocation":46},"/teamops/","teamops",{"title":275,"items":276},"Connect",[277,282,287,292,297],{"text":278,"config":279},"GitLab Services",{"href":280,"dataGaName":281,"dataGaLocation":46},"/services/","services",{"text":283,"config":284},"Community",{"href":285,"dataGaName":286,"dataGaLocation":46},"/community/","community",{"text":288,"config":289},"Forum",{"href":290,"dataGaName":291,"dataGaLocation":46},"https://forum.gitlab.com/","forum",{"text":293,"config":294},"Events",{"href":295,"dataGaName":296,"dataGaLocation":46},"/events/","events",{"text":298,"config":299},"Partners",{"href":300,"dataGaName":301,"dataGaLocation":46},"/partners/","partners",{"backgroundColor":303,"textColor":304,"text":305,"image":306,"link":310},"#2f2a6b","#fff","Insights for the future of software development",{"altText":307,"config":308},"the source promo card",{"src":309},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758208064/dzl0dbift9xdizyelkk4.svg",{"text":311,"config":312},"Read the latest",{"href":313,"dataGaName":314,"dataGaLocation":46},"/the-source/","the source",{"text":316,"config":317,"lists":319},"Company",{"dataNavLevelOne":318},"company",[320],{"items":321},[322,327,333,335,340,345,350,355,360,365,370],{"text":323,"config":324},"About",{"href":325,"dataGaName":326,"dataGaLocation":46},"/company/","about",{"text":328,"config":329,"footerGa":332},"Jobs",{"href":330,"dataGaName":331,"dataGaLocation":46},"/jobs/","jobs",{"dataGaName":331},{"text":293,"config":334},{"href":295,"dataGaName":296,"dataGaLocation":46},{"text":336,"config":337},"Leadership",{"href":338,"dataGaName":339,"dataGaLocation":46},"/company/team/e-group/","leadership",{"text":341,"config":342},"Team",{"href":343,"dataGaName":344,"dataGaLocation":46},"/company/team/","team",{"text":346,"config":347},"Handbook",{"href":348,"dataGaName":349,"dataGaLocation":46},"https://handbook.gitlab.com/","handbook",{"text":351,"config":352},"Investor relations",{"href":353,"dataGaName":354,"dataGaLocation":46},"https://ir.gitlab.com/","investor relations",{"text":356,"config":357},"Trust Center",{"href":358,"dataGaName":359,"dataGaLocation":46},"/security/","trust center",{"text":361,"config":362},"AI Transparency Center",{"href":363,"dataGaName":364,"dataGaLocation":46},"/ai-transparency-center/","ai transparency center",{"text":366,"config":367},"Newsletter",{"href":368,"dataGaName":369,"dataGaLocation":46},"/company/contact/","newsletter",{"text":371,"config":372},"Press",{"href":373,"dataGaName":374,"dataGaLocation":46},"/press/","press",{"text":376,"config":377,"lists":378},"Contact us",{"dataNavLevelOne":318},[379],{"items":380},[381,384,389],{"text":53,"config":382},{"href":55,"dataGaName":383,"dataGaLocation":46},"talk to sales",{"text":385,"config":386},"Get help",{"href":387,"dataGaName":388,"dataGaLocation":46},"/support/","get help",{"text":390,"config":391},"Customer portal",{"href":392,"dataGaName":393,"dataGaLocation":46},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":395,"login":396,"suggestions":403},"Close",{"text":397,"link":398},"To search repositories and projects, login to",{"text":399,"config":400},"gitlab.com",{"href":60,"dataGaName":401,"dataGaLocation":402},"search login","search",{"text":404,"default":405},"Suggestions",[406,408,412,414,418,422],{"text":75,"config":407},{"href":80,"dataGaName":75,"dataGaLocation":402},{"text":409,"config":410},"Code Suggestions (AI)",{"href":411,"dataGaName":409,"dataGaLocation":402},"/solutions/code-suggestions/",{"text":127,"config":413},{"href":129,"dataGaName":127,"dataGaLocation":402},{"text":415,"config":416},"GitLab on AWS",{"href":417,"dataGaName":415,"dataGaLocation":402},"/partners/technology-partners/aws/",{"text":419,"config":420},"GitLab on Google Cloud",{"href":421,"dataGaName":419,"dataGaLocation":402},"/partners/technology-partners/google-cloud-platform/",{"text":423,"config":424},"Why GitLab?",{"href":88,"dataGaName":423,"dataGaLocation":402},{"freeTrial":426,"mobileIcon":431,"desktopIcon":436,"secondaryButton":439},{"text":427,"config":428},"Start free trial",{"href":429,"dataGaName":51,"dataGaLocation":430},"https://gitlab.com/-/trials/new/","nav",{"altText":432,"config":433},"Gitlab Icon",{"src":434,"dataGaName":435,"dataGaLocation":430},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":432,"config":437},{"src":438,"dataGaName":435,"dataGaLocation":430},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":440,"config":441},"Get Started",{"href":442,"dataGaName":443,"dataGaLocation":430},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":445,"mobileIcon":449,"desktopIcon":451},{"text":446,"config":447},"Learn more about GitLab Duo",{"href":80,"dataGaName":448,"dataGaLocation":430},"gitlab duo",{"altText":432,"config":450},{"src":434,"dataGaName":435,"dataGaLocation":430},{"altText":432,"config":452},{"src":438,"dataGaName":435,"dataGaLocation":430},{"freeTrial":454,"mobileIcon":459,"desktopIcon":461},{"text":455,"config":456},"Back to pricing",{"href":208,"dataGaName":457,"dataGaLocation":430,"icon":458},"back to pricing","GoBack",{"altText":432,"config":460},{"src":434,"dataGaName":435,"dataGaLocation":430},{"altText":432,"config":462},{"src":438,"dataGaName":435,"dataGaLocation":430},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":468,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"title":469,"button":470,"image":475,"config":479,"_id":481,"_type":32,"_source":34,"_file":482,"_stem":483,"_extension":37},"/shared/en-us/banner","is now in public beta!",{"text":471,"config":472},"Try the Beta",{"href":473,"dataGaName":474,"dataGaLocation":46},"/gitlab-duo/agent-platform/","duo banner",{"altText":476,"config":477},"GitLab Duo Agent Platform",{"src":478},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1753720689/somrf9zaunk0xlt7ne4x.svg",{"layout":480},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":485,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"data":486,"_id":690,"_type":32,"title":691,"_source":34,"_file":692,"_stem":693,"_extension":37},"/shared/en-us/main-footer",{"text":487,"source":488,"edit":494,"contribute":499,"config":504,"items":509,"minimal":682},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":489,"config":490},"View page source",{"href":491,"dataGaName":492,"dataGaLocation":493},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":495,"config":496},"Edit this page",{"href":497,"dataGaName":498,"dataGaLocation":493},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":500,"config":501},"Please contribute",{"href":502,"dataGaName":503,"dataGaLocation":493},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":505,"facebook":506,"youtube":507,"linkedin":508},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[510,533,589,618,652],{"title":64,"links":511,"subMenu":516},[512],{"text":513,"config":514},"DevSecOps platform",{"href":73,"dataGaName":515,"dataGaLocation":493},"devsecops platform",[517],{"title":206,"links":518},[519,523,528],{"text":520,"config":521},"View plans",{"href":208,"dataGaName":522,"dataGaLocation":493},"view plans",{"text":524,"config":525},"Why Premium?",{"href":526,"dataGaName":527,"dataGaLocation":493},"/pricing/premium/","why premium",{"text":529,"config":530},"Why Ultimate?",{"href":531,"dataGaName":532,"dataGaLocation":493},"/pricing/ultimate/","why ultimate",{"title":534,"links":535},"Solutions",[536,541,543,545,550,555,559,562,566,571,573,576,579,584],{"text":537,"config":538},"Digital transformation",{"href":539,"dataGaName":540,"dataGaLocation":493},"/topics/digital-transformation/","digital transformation",{"text":152,"config":542},{"href":154,"dataGaName":152,"dataGaLocation":493},{"text":141,"config":544},{"href":123,"dataGaName":124,"dataGaLocation":493},{"text":546,"config":547},"Agile development",{"href":548,"dataGaName":549,"dataGaLocation":493},"/solutions/agile-delivery/","agile delivery",{"text":551,"config":552},"Cloud transformation",{"href":553,"dataGaName":554,"dataGaLocation":493},"/topics/cloud-native/","cloud transformation",{"text":556,"config":557},"SCM",{"href":137,"dataGaName":558,"dataGaLocation":493},"source code management",{"text":127,"config":560},{"href":129,"dataGaName":561,"dataGaLocation":493},"continuous integration & delivery",{"text":563,"config":564},"Value stream management",{"href":181,"dataGaName":565,"dataGaLocation":493},"value stream management",{"text":567,"config":568},"GitOps",{"href":569,"dataGaName":570,"dataGaLocation":493},"/solutions/gitops/","gitops",{"text":191,"config":572},{"href":193,"dataGaName":194,"dataGaLocation":493},{"text":574,"config":575},"Small business",{"href":198,"dataGaName":199,"dataGaLocation":493},{"text":577,"config":578},"Public sector",{"href":203,"dataGaName":204,"dataGaLocation":493},{"text":580,"config":581},"Education",{"href":582,"dataGaName":583,"dataGaLocation":493},"/solutions/education/","education",{"text":585,"config":586},"Financial services",{"href":587,"dataGaName":588,"dataGaLocation":493},"/solutions/finance/","financial services",{"title":211,"links":590},[591,593,595,597,600,602,604,606,608,610,612,614,616],{"text":223,"config":592},{"href":225,"dataGaName":226,"dataGaLocation":493},{"text":228,"config":594},{"href":230,"dataGaName":231,"dataGaLocation":493},{"text":233,"config":596},{"href":235,"dataGaName":236,"dataGaLocation":493},{"text":238,"config":598},{"href":240,"dataGaName":599,"dataGaLocation":493},"docs",{"text":261,"config":601},{"href":263,"dataGaName":5,"dataGaLocation":493},{"text":256,"config":603},{"href":258,"dataGaName":259,"dataGaLocation":493},{"text":265,"config":605},{"href":267,"dataGaName":268,"dataGaLocation":493},{"text":278,"config":607},{"href":280,"dataGaName":281,"dataGaLocation":493},{"text":270,"config":609},{"href":272,"dataGaName":273,"dataGaLocation":493},{"text":283,"config":611},{"href":285,"dataGaName":286,"dataGaLocation":493},{"text":288,"config":613},{"href":290,"dataGaName":291,"dataGaLocation":493},{"text":293,"config":615},{"href":295,"dataGaName":296,"dataGaLocation":493},{"text":298,"config":617},{"href":300,"dataGaName":301,"dataGaLocation":493},{"title":316,"links":619},[620,622,624,626,628,630,632,636,641,643,645,647],{"text":323,"config":621},{"href":325,"dataGaName":318,"dataGaLocation":493},{"text":328,"config":623},{"href":330,"dataGaName":331,"dataGaLocation":493},{"text":336,"config":625},{"href":338,"dataGaName":339,"dataGaLocation":493},{"text":341,"config":627},{"href":343,"dataGaName":344,"dataGaLocation":493},{"text":346,"config":629},{"href":348,"dataGaName":349,"dataGaLocation":493},{"text":351,"config":631},{"href":353,"dataGaName":354,"dataGaLocation":493},{"text":633,"config":634},"Sustainability",{"href":635,"dataGaName":633,"dataGaLocation":493},"/sustainability/",{"text":637,"config":638},"Diversity, inclusion and belonging (DIB)",{"href":639,"dataGaName":640,"dataGaLocation":493},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":356,"config":642},{"href":358,"dataGaName":359,"dataGaLocation":493},{"text":366,"config":644},{"href":368,"dataGaName":369,"dataGaLocation":493},{"text":371,"config":646},{"href":373,"dataGaName":374,"dataGaLocation":493},{"text":648,"config":649},"Modern Slavery Transparency Statement",{"href":650,"dataGaName":651,"dataGaLocation":493},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":653,"links":654},"Contact Us",[655,658,660,662,667,672,677],{"text":656,"config":657},"Contact an expert",{"href":55,"dataGaName":56,"dataGaLocation":493},{"text":385,"config":659},{"href":387,"dataGaName":388,"dataGaLocation":493},{"text":390,"config":661},{"href":392,"dataGaName":393,"dataGaLocation":493},{"text":663,"config":664},"Status",{"href":665,"dataGaName":666,"dataGaLocation":493},"https://status.gitlab.com/","status",{"text":668,"config":669},"Terms of use",{"href":670,"dataGaName":671,"dataGaLocation":493},"/terms/","terms of use",{"text":673,"config":674},"Privacy statement",{"href":675,"dataGaName":676,"dataGaLocation":493},"/privacy/","privacy statement",{"text":678,"config":679},"Cookie preferences",{"dataGaName":680,"dataGaLocation":493,"id":681,"isOneTrustButton":109},"cookie preferences","ot-sdk-btn",{"items":683},[684,686,688],{"text":668,"config":685},{"href":670,"dataGaName":671,"dataGaLocation":493},{"text":673,"config":687},{"href":675,"dataGaName":676,"dataGaLocation":493},{"text":678,"config":689},{"dataGaName":680,"dataGaLocation":493,"id":681,"isOneTrustButton":109},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",[695],{"_path":696,"_dir":697,"_draft":6,"_partial":6,"_locale":7,"content":698,"config":702,"_id":704,"_type":32,"title":18,"_source":34,"_file":705,"_stem":706,"_extension":37},"/en-us/blog/authors/michael-friedrich","authors",{"name":18,"config":699},{"headshot":700,"ctfId":701},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659879/Blog/Author%20Headshots/dnsmichi-headshot.jpg","dnsmichi",{"template":703},"BlogAuthor","content:en-us:blog:authors:michael-friedrich.yml","en-us/blog/authors/michael-friedrich.yml","en-us/blog/authors/michael-friedrich",{"_path":708,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"header":709,"eyebrow":710,"blurb":711,"button":712,"secondaryButton":716,"_id":718,"_type":32,"title":719,"_source":34,"_file":720,"_stem":721,"_extension":37},"/shared/en-us/next-steps","Start shipping better software faster","50%+ of the Fortune 100 trust GitLab","See what your team can do with the intelligent\n\n\nDevSecOps platform.\n",{"text":48,"config":713},{"href":714,"dataGaName":51,"dataGaLocation":715},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":53,"config":717},{"href":55,"dataGaName":56,"dataGaLocation":715},"content:shared:en-us:next-steps.yml","Next Steps","shared/en-us/next-steps.yml","shared/en-us/next-steps",1758326267761]