chore: added coderpad sponsorship and blog post

This commit is contained in:
Corbin Crutchley
2021-05-04 16:59:36 -07:00
parent d8ac6427da
commit 64f5a9ddff
7 changed files with 541 additions and 1 deletions

View File

@@ -1,3 +1,4 @@
{
"useTabs": true
"useTabs": true,
"endOfLine": "auto"
}

View File

@@ -18,6 +18,7 @@ This repository acts as the source code location for [the Unicorn Utterances blo
<a href="https://www.thepolyglotdeveloper.com/" target="_blank" rel="noopener noreferrer sponsored"><img alt="The Polyglot Developer" src="https://unicorn-utterances.com/sponsors/the-polyglot-developer.svg" width="300"/></a>
<a href="https://oceanbit.dev/" target="_blank" rel="noopener noreferrer sponsored"><img alt="OceanBit" src="https://unicorn-utterances.com/sponsors/oceanbit.svg" width="300"/></a>
<a href="https://coderpad.io/" target="_blank" rel="noopener noreferrer sponsored"><img alt="CoderPad" src="https://unicorn-utterances.com/sponsors/coderpad.svg" width="300"/></a>
## Statement of Ethics

View File

@@ -0,0 +1,511 @@
---
{
title: "Rust Enums, Matching, & Options API",
description: "",
published: '2021-04-16T22:12:03.284Z',
authors: ['crutchcorn'],
tags: ['rust'],
attached: [],
license: 'coderpad',
originalLink: 'https://coderpad.io/blog/rust-enums-matching-options-api/'
}
---
If youve been active in the programming community within the past few years, youve undoubtedly heard of [Rust](https://www.rust-lang.org/). Its technical foundation and vibrant community have proven themselves to be a good benchmark for quick language growth.
But what does Rust do that has garnered such a positive response from the community? Not only does Rust provide a great deal of memory safety (something thats rare in low-level languages in the past), but also includes powerful features that make development much nicer.
One of the many features that highlights Rusts capabilities is its handling of enums and matching.
## Enums
Like many languages with strict typings, Rust [has an enum feature](https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html). To declare an enum is simple enough, start with `pub enum` and name the values.
```rust
pub enum CodeLang {
Rust,
JavaScript,
Swift,
Kotlin,
// ...
}
```
To create a variable with the type of that enum, you can use the name of the enum with the value:
```rust
fn main() {
let lang = CodeLang::Rust;
}
```
Likewise, you can use the `enum` as a type in places like function params. Lets say that you want to detect which version of a programming language supported in CoderPad. Well start by hard-coding the version of Rust:
```rust
fn get_version(_lang: CodeLang) -> &'static str {
return "1.46";
}
```
While this code *works*, its not very functional. If you pass in “CodeLang::JavaScript”, the version number isnt correct. Lets take a look at how we can fix that in the next section.
## Matching
While you *could* use `if` statements to detect which enum is passed in, like so:
```rust
fn get_version(lang: CodeLang) -> &'static str {
if let CodeLang::Rust = lang {
return "1.46";
}
if let CodeLang::JavaScript = lang {
return "2021";
}
return ""
}
fn main() {
let lang = CodeLang::Rust;
let ver = get_version(lang);
println!("Version {}", ver);
}
```
This easily becomes unwieldy when dealing with more than one or two values in the enum. This is where Rusts `match` operator comes into play. Lets match the variable with all of the existing values in the enum:
```rust
fn get_version(lang: CodeLang) -> &'static str {
match lang {
CodeLang::Rust => "1.46",
CodeLang::JavaScript => "2021",
CodeLang::Swift => "5.3",
CodeLang::Python => "3.8"
}
}
```
If youre familiar with a programming language that has a feature similar to “[switch/case](https://www.tutorialspoint.com/cprogramming/switch_statement_in_c.htm)”, this example is a close approximation of that functionality. However, as youll soon see, `match` in Rust is significantly more powerful than most implementations of switch/case.
## Pattern Matching
While most implementations of `switch/case` only allow simple primitives matching, such as strings or numbers, Rusts `match` allows you to have more granular control over what is matched and how. For example, you can match anything that isnt matched otherwise using the `_` identifier:
```rust
fn get_version(lang: CodeLang) -> &'static str {
match lang {
CodeLang::Rust => "1.46",
_ => "Unknown version"
}
}
```
You are also able to match more than a single value at a time. In this example, were doing a check on versions for more than one programming language at a time.
```rust
fn get_version<'a>(lang: CodeLang, other_lang: CodeLang) -> (&'a str, &'a str) {
match (lang, other_lang) {
(CodeLang::Rust, CodeLang::Python) => ("1.46", "3.8"),
_ => ("Unknown", "Unknown")
}
}
```
This shows some of the power of `match` . However, theres more that youre able to do with enums.
## Value Storage
Not only are enums values within themselves, but you can also store values within enums to be accessed later.
For example, CoderPad supports two different versions of Python. However, instead of creating a `CodeLang::Python` and `CoderLang::Python2` enum values, we can use one value and store the major version within.
```rust
pub enum CodeLang {
Rust,
JavaScript,
Swift,
Python(u8),
// ...
}
fn main() {
let python2 = CodeLang::Python(2);
let pythonVer = get_version(python2);
}
```
Were able to expand our `if let` expression from before to access the value within:
```rust
if let CodeLang::Python(ver) = python2 {
println!("Python version is {}", ver);
}
```
However, just as before, were able to leverage `match` to unpack the value within the enum:
```rust
fn get_version(lang: CodeLang) -> &'static str {
match lang {
CodeLang::Rust => "1.46",
CodeLang::JavaScript => "2021",
CodeLang::Python(ver) => {
if ver == 3 { "3.8" } else { "2.7" }
},
_ => "Unknown"
}
}
```
Not all enums need to be manually set, however! Rust has some enums built-in to the language, ready for use.
## Option Enum
While were currently returning the string `”Unknown”` as a version, thats not ideal. Namely, wed have to do a string comparison to check if were returning a known version or not, rather than having a value dedicated to a lack of value.
This is where Rusts `Option` enum comes into play. `Option<T>` describes a data type that either has `Some(data)` or `None` to speak of.
For example, we can rewrite the above function to:
```rust
fn get_version<'a>(lang: CodeLang) -> Option<&'a str> {
match lang {
CodeLang::Rust => Some("1.46"),
CodeLang::JavaScript => Some("2021"),
CodeLang::Python(ver) => {
if ver == 3 { Some("3.8") } else { Some("2.7") }
},
_ => None
}
}
```
By doing this, we can make our logic more representative and check if a value is `None`
```rust
fn main() {
let swift_version = get_version(CodeLang::Swift);
if let None = swift_version {
println!("We could not find a valid version of your tool");
return;
}
}
```
Finally, we can of course use `match` to migrate from an `if` to check when values are set:
```rust
fn main() {
let code_version = get_version(CodeLang::Rust);
match code_version {
Some(val) => {
println!("Your version is {}", val);
},
None => {
println!("We could not find a valid version of your tool");
return;
}
}
}
```
## Operators
While the above code functions as intended, if we add more conditional logic, we may find ourselves wanting to make abstractions. Lets look at some of these abstractions Rust provides for us
### Map Operator
What if we wanted to convert `rust_version` to a string, but wanted to handle edge-cases where `None` was present.
You might write something like this:
```rust
fn main() {
let rust_version = get_version(CodeLang::Rust);
let version_str = match rust_version {
Some(val) => {
Some(format!("Your version is {}", val))
},
None => None
};
if let Some(val) = version_str {
println!("{}", val);
return;
}
}
```
This `match` of taking `Some` and mapping it to a new value and leaving `None` s to resolve as `None` still is baked into the Option enum as a method called `.map` :
```rust
fn main() {
let rust_version = get_version(CodeLang::Rust);
let version_str = rust_version.map(|val| {
format!("Your version is {}", val)
});
if let Some(val) = version_str {
println!("{}", val);
return;
}
}
```
How close is the implementation of `.map` to what we were doing before? Lets take a look at [Rusts source code implementation of `.map` ](https://github.com/rust-lang/rust/blob/8dc0ae24bcafeb52259ae20fcad29185acf31fcc/library/core/src/option.rs#L485-L490):
```rust
pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {
match self {
Some(x) => Some(f(x)),
None => None,
}
}
```
As you can see, we matched our implementation very similarly, matching `Some` to another `Some` and `None` to another `None`
### And Then Operator
While the automatic wrapping of the `.map` function return value into a `Some` can be useful in most instances, there may be times where you want to conditionally make something inside the `map`
Lets say that we only want version numbers that contain a dot (indicating theres a minor version). We could do something like this:
```rust
fn main() {
let rust_version = get_version(CodeLang::JavaScript);
let version_str = match rust_version {
Some(val) => {
if val.contains(".") {
Some(format!("Your version is {}", val))
} else {
None
}
},
None => None
};
if let Some(val) = version_str {
println!("{}", val);
return;
}
}
```
Which we can rewrite using Rusts `and_then` operator:
```rust
fn main() {
let rust_version = get_version(CodeLang::JavaScript);
let version_str = rust_version.and_then(|val| {
if val.contains(".") {
Some(format!("Your version is {}", val))
} else {
None
}
});
if let Some(val) = version_str {
println!("{}", val);
return;
}
}
```
If we look at [Rusts source code for the operator](https://github.com/rust-lang/rust/blob/8dc0ae24bcafeb52259ae20fcad29185acf31fcc/library/core/src/option.rs#L722-L727), we can see the similarity to the `.map` implementation, simply without wrapping `fn` in `Some` :
```rust
pub fn and_then<U, F: FnOnce(T) -> Option<U>>(self, f: F) -> Option<U> {
match self {
Some(x) => f(x),
None => None,
}
}
```
## Putting it Together
Now that were familiar with the Option enum, operators, and pattern matching lets put it all together!
Lets start with the same `get_version` function baseline weve been using for a few examples:
```rust
use regex::Regex;
pub enum CodeLang {
Rust,
JavaScript,
Swift,
Python(u8),
// ...
}
fn get_version<'a>(lang: CodeLang) -> Option<&'a str> {
match lang {
CodeLang::Rust => Some("1.46"),
CodeLang::JavaScript => Some("2021"),
CodeLang::Python(ver) => {
if ver == 3 { Some("3.8") } else { Some("2.7") }
},
_ => None
}
}
fn main() {
let lang = CodeLang::JavaScript;
let lang_version = get_version(lang);
}
```
Given this baseline, lets build a semver checker. Given a coding language, tell us what the major and minor versions of that language are.
For example, Rust (1.46) would return “**Major: 1. Minor: 46**”, while JavaScript (2021) would return **“Major: 2021. Minor: 0**”
Well do this check using a Regex that parses any dots in the version string.
```
(\d+)(?:\.(\d+))?
```
This regex will match the first capture group as anything before the first period, then optionally provide a second capture if there is a period, matching anything after that period. Lets add that Regex and the captures in our `main` function:
```rust
let version_regex = Regex::new(r"(\d+)(?:\.(\d+))?").unwrap();
let version_matches = lang_version.and_then(|version_str| {
return version_regex.captures(version_str);
});
```
In the code sample above, were using `and_then` in order to flatten `captures` into a single-layer `Option` enum - seeing as `lang_version` is an Option itself and `captures` returns an Option as well.
While `.captures` sounds like it should return an array of the capture strings, in reality it returns [a structure with various methods and properties](https://docs.rs/regex/1.1.9/regex/struct.Captures.html). To get the strings for each of these values, well use `version_matches.map` to get both of these capture group strings:
```rust
let major_minor_captures = version_matches
.map(|caps| {
(
caps.get(1).map(|m| m.as_str()),
caps.get(2).map(|m| m.as_str()),
)
});
```
While wed expect capture group 1 to always provide a value (given our input), wed see “None” returned in capture group 2 if theres no period (like with JavaScripts version number of “2021”). Because of this, there are instances where `caps.get(2)` may be `None` . As such, we want to make sure to get a `0` in the place of `None` and convert the `Some<&str>, Option<&str>` into `Some<&str, &str>` . To do this, well use `and_then` and a `match` :
```rust
let major_minor = major_minor_captures
.and_then(|(first_opt, second_opt)| {
match (first_opt, second_opt) {
(Some(major), Some(minor)) => Some((major, minor)),
(Some(major), None) => Some((major, "0")),
_ => None,
}
});
```
Finally, we can use an `if let` to deconstruct the values and print the major and minor versions:
```rust
if let Some((first, second)) = major_minor {
println!("Major: {}. Minor: {}", first, second);
}
```
The final version of the project should look something like this:
```rust
use regex::Regex;
pub enum CodeLang {
Rust,
JavaScript,
Swift,
Python(u8),
// ...
}
fn get_version<'a>(lang: CodeLang) -> Option<&'a str> {
match lang {
CodeLang::Rust => Some("1.46"),
CodeLang::JavaScript => Some("2021"),
CodeLang::Python(ver) => {
if ver == 3 { Some("3.8") } else { Some("2.7") }
},
_ => None
}
}
fn main() {
let lang = CodeLang::JavaScript;
let lang_version = get_version(lang);
let version_regex = Regex::new(r"(\d+)(?:\.(\d+))?").unwrap();
let version_matches = lang_version.and_then(|version_str| {
return version_regex.captures(version_str);
});
let major_minor_captures = version_matches
.map(|caps| {
(
caps.get(1).map(|m| m.as_str()),
caps.get(2).map(|m| m.as_str()),
)
});
let major_minor = major_minor_captures
.and_then(|(first_opt, second_opt)| {
match (first_opt, second_opt) {
(Some(major), Some(minor)) => Some((major, minor)),
(Some(major), None) => Some((major, "0")),
_ => None,
}
});
if let Some((first, second)) = major_minor {
println!("Major: {}. Minor: {}", first, second);
}
}
```
## Conclusion & Challenge
All of these features are used regularly in Rust applications: enums, matching, option operators. We hope that you can take these features and utilize them in your applications along your journey to learn Rust.
Lets close with a challenge. If you get stuck anywhere along the way or have comments/questions about this article, you can join our[ public chat community where we talk about general coding topics as well as interviewing](http://bit.ly/coderpad-slack).
Lets say that we have the “patch” version of a software tracked. We want to expand the logic of our code to support checking “5.1.2” and return “2” as the “patch” version. Given the modified regex to support three optional capture groups:
```
(\d+)(?:\.(\d+))?(?:\.(\d+))?
```
How can you modify the code below to support the match version being listed out properly?
<iframe src="https://app.coderpad.io/sandbox?question_id=175664" width="640" height="480" loading="lazy"></iframe>
Youll know the code is working when youre able to output the following:
```
Major: 2021. Minor: 0, Patch: 0
Major: 1. Minor: 46, Patch: 0
Major: 5. Minor: 1, Patch: 2
```

View File

@@ -30,5 +30,13 @@
"explainLink": "https://creativecommons.org/licenses/by-nc-nd/4.0/",
"name": "Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)",
"displayName": "Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) License"
},
{
"id": "coderpad",
"footerImg": "/coderpad.png",
"licenceType": "Owned by CoderPad",
"explainLink": "https://coderpad.io/about-us/",
"name": "Written for CoderPad, reposted to Unicorn Utterances",
"displayName": "Written for CoderPad"
}
]

View File

@@ -70,6 +70,11 @@ As mentioned previously, we also have a Discord where we chat tech, help out wit
">
<a href="https://oceanbit.dev/" target="_blank" rel="noopener noreferrer sponsored"><img alt="OceanBit" src="/sponsors/oceanbit.svg" style="width: 300px; margin: 0"/></a>
</li>
<li style="
margin: 16px;
">
<a href="https://coderpad.io/" target="_blank" rel="noopener noreferrer sponsored"><img alt="CoderPad" src="/sponsors/coderpad.svg" style="width: 300px; margin: 0"/></a>
</li>
</ul>
## Statement of Ethics {#ethics}

BIN
static/coderpad.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@@ -0,0 +1,14 @@
<svg width="475" height="67" viewBox="0 0 475 67" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M474.76 65.1389L456.947 65.8479L456.149 61.328C452.693 64.7844 448.35 66.6455 443.387 66.6455C437.538 66.6455 433.284 64.6958 430.271 60.6191C427.346 56.631 426.017 51.1363 426.017 43.8691C426.017 35.8929 427.967 29.7778 432.044 25.4352C436.032 21.1812 441.969 18.877 449.946 18.877C451.807 18.877 453.668 19.0542 455.352 19.6746V9.03967L448.616 7.44444V0.708984L464.391 0L465.987 1.86109L467.582 3.27909V56.4537L474.406 58.049L474.76 65.1389ZM455.44 51.8453V30.3095C453.934 29.5119 451.984 28.9802 448.794 28.9802C442.324 28.9802 438.956 33.7659 438.956 43.3373C438.956 52.377 441.615 56.8082 447.11 56.8082C448.705 56.8082 450.3 56.5423 451.364 55.4788C452.87 54.6812 453.756 53.8836 454.288 53.086L455.44 51.8453Z" fill="#CC4E41"/>
<path d="M114.237 16.9272C111.578 15.8637 108.388 15.5979 104.754 15.5979C95.4484 15.5979 90.7513 22.3333 90.7513 36.336C90.7513 49.2751 95.537 55.7447 105.286 55.7447C107.767 55.7447 110.426 55.213 112.819 54.2381C115.478 53.1746 117.604 52.2884 119.022 51.3135L120.972 49.8955L125.581 57.6058C125.492 57.6945 124.872 58.3148 124.694 58.6693C124.251 58.9352 123.188 59.8214 121.77 61.0622C120.263 62.1257 118.579 63.0119 117.161 63.8095C115.566 64.6072 113.439 65.3161 111.046 65.9365C108.565 66.6455 106.261 67 103.779 67C95.0939 67 88.5357 64.3413 83.75 59.2897C79.1415 54.0608 76.66 46.705 76.66 36.9563C76.66 27.119 79.3188 19.4087 84.459 13.7368C89.5992 8.15343 96.4233 5.22882 105.374 5.22882C108.299 5.22882 111.578 5.49468 114.769 6.2923C117.959 7.08992 120.618 7.62167 122.39 8.24204L125.049 9.30555L124.34 25.2579H116.098L114.237 16.9272Z" fill="#515050"/>
<path d="M154.384 19.3201C161.119 19.3201 166.348 21.2698 170.247 25.3465C173.969 29.3346 175.919 34.918 175.919 42.0966C175.919 49.8069 173.969 55.4788 169.804 59.9987C165.639 64.5185 160.233 66.4683 153.32 66.4683C139.14 66.4683 131.784 58.7579 131.784 43.2487C131.784 35.5384 133.734 29.8664 137.899 25.7011C141.622 21.2698 147.471 19.3201 154.384 19.3201ZM153.852 28.8915C150.661 28.8915 148.091 29.955 146.762 32.082C145.432 34.209 144.369 37.6653 144.369 42.8942C144.369 47.6799 145.078 51.4021 146.319 53.5291C147.825 55.922 150.041 56.8968 153.143 56.8968C156.333 56.8968 158.46 55.8333 159.878 53.5291C161.385 51.4021 162.005 47.5026 162.005 42.6283C162.005 38.0198 161.296 34.6521 160.055 32.5251C158.992 30.0436 156.865 28.8915 153.852 28.8915Z" fill="#515050"/>
<path d="M229.98 65.1389L212.167 65.8479L211.458 61.328C208.001 64.7844 203.57 66.6455 198.696 66.6455C192.846 66.6455 188.593 64.6958 185.579 60.6191C182.655 56.631 181.325 51.1363 181.325 43.8691C181.325 35.8929 183.275 29.7778 187.352 25.4352C191.34 21.1812 197.278 18.877 205.254 18.877C207.115 18.877 208.976 19.0542 210.66 19.6746V9.03967L203.925 7.44444V0.708984L219.877 0L221.738 1.86109L223.245 3.27909V56.4537L229.98 58.049V65.1389ZM210.571 51.8453V30.3095C209.065 29.5119 206.849 28.9802 204.013 28.9802C197.544 28.9802 194.176 33.7659 194.176 43.3373C194.176 52.377 196.835 56.8082 202.241 56.8082C203.747 56.8082 205.431 56.5423 206.761 55.4788C208.179 54.6812 209.153 53.8836 209.685 53.086L210.571 51.8453Z" fill="#515050"/>
<path d="M275.71 45.3756L247.616 45.6415C247.794 49.0979 248.946 52.0225 250.807 53.795C252.668 55.6561 254.884 56.7196 257.72 56.7196C259.669 56.7196 261.974 56.4537 264.366 55.6561C266.759 54.8585 268.62 54.3267 269.773 53.7063L271.722 52.6429L275.444 59.3783C274.735 59.9101 274.026 60.619 272.786 61.2394C271.634 62.037 269.329 63.1005 266.05 64.4299C262.594 65.7593 259.403 66.3796 256.213 66.3796C249.034 66.3796 243.628 64.4299 239.729 60.3532C236.007 56.3651 234.057 50.7817 234.057 43.6032C234.057 36.1587 236.007 30.1323 240.083 25.7011C244.071 21.4471 249.655 19.0542 256.745 19.0542C263.037 19.0542 267.646 20.9153 271.013 24.3717C274.381 27.828 276.065 32.8796 276.065 38.9947L275.71 45.3756ZM256.036 28.9801C253.643 28.9801 251.959 29.7778 250.364 31.373C248.769 32.9682 247.971 35.0952 247.705 37.6653H262.86C262.86 32.082 260.733 28.9801 256.036 28.9801Z" fill="#515050"/>
<path d="M281.471 20.7381L299.019 20.0291L299.728 25.8783C299.993 25.3466 300.702 24.6376 301.589 24.0172C302.475 23.3082 303.982 22.1561 305.843 21.0926C307.792 19.9405 309.831 19.2315 311.515 19.2315C312.844 19.2315 314.173 19.3201 315.503 19.586C316.832 19.8518 317.896 20.1177 318.339 20.3836L319.136 20.6495L318.427 36.7791H311.16L309.831 29.5119C308.413 29.5119 306.906 29.8664 305.311 30.664C303.716 31.4616 302.652 32.1706 301.855 32.9683L300.702 34.209V56.8082L308.767 58.758V65.4934H281.471V58.758L288.295 56.8082V29.1574L281.471 27.5622V20.7381Z" fill="#515050"/>
<path d="M349.534 58.2262V65.4934H323.745V58.2262L330.037 56.2765V16.041L323.745 13.5595V6.64682L343.154 6.2923H351.307C357.776 6.2923 362.739 7.71031 366.462 11.078C370.184 14.2685 371.956 18.5225 371.956 24.2831C371.956 31.1958 370.007 36.5132 365.575 40.0582C361.41 43.5145 355.472 45.3756 347.673 45.3756H343.065V56.5423L349.534 58.2262ZM342.976 16.1296V35.0066H347.496C350.952 35.0066 353.877 34.209 355.65 32.5251C357.511 30.9299 358.486 28.537 358.486 25.6124C358.486 22.7764 357.688 20.3836 356.093 18.7883C354.497 17.1931 352.37 16.1296 349.623 16.1296H342.976Z" fill="#CC4E41"/>
<path d="M421.586 65.1389L404.836 65.8479L403.418 60.4418C402.886 60.7077 402.177 61.5053 401.468 62.3029C400.671 63.1005 398.898 63.8982 396.417 65.1389C393.935 66.291 391.808 67 389.593 67C385.516 67 382.325 65.8479 380.021 63.5437C377.628 61.2394 376.565 57.9603 376.565 53.7063C376.565 44.4008 383.389 39.7037 396.948 39.7037H402.798V35.0952C402.798 30.8413 400.671 28.8029 396.328 28.8029C394.999 28.8029 393.758 28.9802 392.429 29.0688C391.099 29.246 390.302 29.4233 389.681 29.7778L388.884 29.955L387.554 35.3611H379.933L379.224 22.7764C386.048 20.3836 392.251 19.3201 397.569 19.3201C404.038 19.3201 408.47 20.6495 411.217 23.0423C413.876 25.4352 415.205 29.7778 415.205 35.9815V56.9855L421.497 58.4034L421.586 65.1389ZM388.706 52.0225C388.706 55.4788 390.302 57.2513 393.758 57.2513C395.087 57.2513 396.417 56.8968 397.923 55.922C399.341 54.8585 400.582 54.3267 401.38 53.3518L402.709 52.1997V46.6164H397.923C394.556 46.6164 392.163 46.9709 391.011 47.9458C389.415 48.6548 388.706 50.1614 388.706 52.0225Z" fill="#CC4E41"/>
<path d="M56.8082 2.48148H50.1614H4.96297C2.12699 2.48148 0 4.60847 0 7.44445V52.2884V59.1124C0 61.9484 2.12699 64.0754 4.96297 64.0754H11.6098H56.8082C59.5556 64.0754 61.7712 61.9484 61.7712 59.1124V14.2685V7.44445C61.7712 4.60847 59.6442 2.48148 56.8082 2.48148Z" fill="#CC4E41"/>
<path d="M12.5848 34.1204L22.5993 37.6654V42.6283L7.44458 36.2474V32.082L22.5993 25.7011V30.664L12.5848 34.1204Z" fill="white"/>
<path d="M28.3599 47.1481H24.6377L34.0319 19.4087H37.8427L28.3599 47.1481Z" fill="white"/>
<path d="M49.0979 34.1204L38.9061 30.5754V25.7011L54.1495 32.082V36.2474L38.9061 42.6283V37.754L49.0979 34.1204Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 6.8 KiB