Repository: JanDeDobbeleer/oh-my-posh
Pull request #836 (2021-07-04 19:29:32)

feat: rust segment
### Prerequisites

- [x] I have read and understood the `CONTRIBUTING` guide
- [x] The commit message follows the [conventional commits][cc] guidelines
- [x] Tests for the changes have been added (for bug fixes/features)
- [x] Docs have been added / updated (for bug fixes/features)

### Description

This adds support for the rust language! 😄 Uses the command `rustc --version` and enables when `*.rs`, `Cargo.toml` or `Cargo.lock` files are present.

### PS

Hey, this is my first ever contribution to on open-source project, I hope I did everything right. ^^ However, I never programmed anything in Go before and used the examples from other language segments (mostly from dart and ruby).

I really love oh-my-posh, its really great, so thank you for programming this. 👍🏻

LG Tobi :) 

[cc]: https://www.conventionalcommits.org/en/v1.0.0/#summary



Patch:
diff --git a/docs/docs/segment-rust.md b/docs/docs/segment-rust.md
new file mode 100644
index 00000000..0cb8facc
--- /dev/null
+++ b/docs/docs/segment-rust.md
@@ -0,0 +1,33 @@
+---
+id: rust
+title: Rust
+sidebar_label: Rust
+---
+
+## What
+
+Display the currently active rust version.
+
+## Sample Configuration
+
+```json
+{
+  "type": "rust",
+  "style": "powerline",
+  "powerline_symbol": "\uE0B0",
+  "foreground": "#193549",
+  "background": "#99908a",
+  "properties": {
+    "prefix": " \uE7a8 "
+  }
+}
+```
+
+## Properties
+
+- display_version: `boolean` - display the rust version (`rustc --version`) - defaults to `true`
+- display_error: `boolean` - show the error context when failing to retrieve the version information - defaults to `true`
+- missing_command_text: `string` - text to display when the command is missing - defaults to empty
+- display_mode: `string` - determines when the segment is displayed
+  - `always`: the segment is always displayed
+  - `files`: the segment is only displayed when `*.rs`, `Cargo.toml` or `Cargo.lock` files are present (default)
diff --git a/docs/sidebars.js b/docs/sidebars.js
index 2d51b97d..e8d06455 100644
--- a/docs/sidebars.js
+++ b/docs/sidebars.js
@@ -9,12 +9,7 @@ module.exports = {
         {
           type: "category",
           label: "🚀 Installation",
-          items: [
-            "pwsh",
-            "windows",
-            "macos",
-            "linux",
-          ],
+          items: ["pwsh", "windows", "macos", "linux"],
         },
         "configure",
         "beta",
@@ -22,7 +17,7 @@ module.exports = {
         "share",
         "fonts",
         "faq",
-        "contributors"
+        "contributors",
       ],
     },
     {
@@ -53,6 +48,7 @@ module.exports = {
         "python",
         "root",
         "ruby",
+        "rust",
         "session",
         "shell",
         "spotify",
@@ -60,12 +56,16 @@ module.exports = {
         "text",
         "time",
         "ytm",
-      ]
+      ],
     },
     {
       type: "category",
       label: "Contributing",
-      items: ["contributing_started", "contributing_segment", "contributing_git"],
+      items: [
+        "contributing_started",
+        "contributing_segment",
+        "contributing_git",
+      ],
     },
   ],
 };
diff --git a/src/segment.go b/src/segment.go
index 6f477ab4..58f6d1a4 100644
--- a/src/segment.go
+++ b/src/segment.go
@@ -119,6 +119,8 @@ const (
 	Dart SegmentType = "dart"
 	// Nbgv writes the nbgv version information
 	Nbgv SegmentType = "nbgv"
+	// Rust writes the cargo version information if cargo.toml is present
+	Rust SegmentType = "rust"
 )
 
 func (segment *Segment) string() string {
@@ -258,6 +260,7 @@ func (segment *Segment) mapSegmentWithWriter(env environmentInfo) error {
 		Crystal:       &crystal{},
 		Dart:          &dart{},
 		Nbgv:          &nbgv{},
+		Rust:          &rust{},
 	}
 	if writer, ok := functions[segment.Type]; ok {
 		props := &properties{
diff --git a/src/segment_rust.go b/src/segment_rust.go
new file mode 100644
index 00000000..a0396cf5
--- /dev/null
+++ b/src/segment_rust.go
@@ -0,0 +1,28 @@
+package main
+
+type rust struct {
+	language *language
+}
+
+func (r *rust) string() string {
+	return r.language.string()
+}
+
+func (r *rust) init(props *properties, env environmentInfo) {
+	r.language = &language{
+		env:        env,
+		props:      props,
+		extensions: []string{"*.rs", "Cargo.toml", "Cargo.lock"},
+		commands: []*cmd{
+			{
+				executable: "rustc",
+				args:       []string{"--version"},
+				regex:      `rustc (?P<version>((?P<major>[0-9]+).(?P<minor>[0-9]+).(?P<patch>[0-9]+)))`,
+			},
+		},
+	}
+}
+
+func (r *rust) enabled() bool {
+	return r.language.enabled()
+}
diff --git a/themes/schema.json b/themes/schema.json
index 5ecc6439..69413e81 100644
--- a/themes/schema.json
+++ b/themes/schema.json
@@ -154,7 +154,8 @@
             "poshgit",
             "azfunc",
             "crystal",
-            "dart"
+            "dart",
+            "rust"
           ]
         },
         "style": {
@@ -828,6 +829,32 @@
             }
           }
         },
+        {
+          "if": {
+            "properties": {
+              "type": { "const": "rust" }
+            }
+          },
+          "then": {
+            "title": "Rust Segment",
+            "description": "https://ohmyposh.dev/docs/rust",
+            "properties": {
+              "properties": {
+                "properties": {
+                  "display_version": {
+                    "$ref": "#/definitions/display_version"
+                  },
+                  "display_mode": {
+                    "$ref": "#/definitions/display_mode"
+                  },
+                  "missing_command_text": {
+                    "$ref": "#/definitions/missing_command_text"
+                  }
+                }
+              }
+            }
+          }
+        },
         {
           "if": {
             "properties": {


Test patch:
diff --git a/src/segment_rust_test.go b/src/segment_rust_test.go
new file mode 100644
index 00000000..1773cde7
--- /dev/null
+++ b/src/segment_rust_test.go
@@ -0,0 +1,31 @@
+package main
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestRust(t *testing.T) {
+	cases := []struct {
+		Case           string
+		ExpectedString string
+		Version        string
+	}{
+		{Case: "Rust 1.53.0", ExpectedString: "1.53.0", Version: "rustc 1.53.0 (4369396ce 2021-04-27)"},
+	}
+	for _, tc := range cases {
+		params := &mockedLanguageParams{
+			cmd:           "rustc",
+			versionParam:  "--version",
+			versionOutput: tc.Version,
+			extension:     "*.rs",
+		}
+		env, props := getMockedLanguageEnv(params)
+		r := &rust{}
+		r.init(props, env)
+		assert.True(t, r.enabled(), fmt.Sprintf("Failed in case: %s", tc.Case))
+		assert.Equal(t, tc.ExpectedString, r.string(), fmt.Sprintf("Failed in case: %s", tc.Case))
+	}
+}