<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: YJDoc2</title>
    <description>The latest articles on DEV Community by YJDoc2 (@yjdoc2).</description>
    <link>https://dev.to/yjdoc2</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F468876%2F7e3ab1e1-0952-4b5f-8897-e93a5871247d.png</url>
      <title>DEV Community: YJDoc2</title>
      <link>https://dev.to/yjdoc2</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yjdoc2"/>
    <language>en</language>
    <item>
      <title>Two Rust features that I miss in Other languages</title>
      <dc:creator>YJDoc2</dc:creator>
      <pubDate>Thu, 13 Apr 2023 14:35:34 +0000</pubDate>
      <link>https://dev.to/yjdoc2/two-rust-features-that-i-miss-in-other-languages-7ec</link>
      <guid>https://dev.to/yjdoc2/two-rust-features-that-i-miss-in-other-languages-7ec</guid>
      <description>&lt;p&gt;Hello everyone!&lt;/p&gt;

&lt;p&gt;Now-a-days I am writing code in several different languages : Rust, C , JavaScript, Python. While all of these have their own use cases , Rust is one of my favorite languages in which I enjoy writing code in.&lt;/p&gt;

&lt;p&gt;I have been writing code in Rust for about 1.5 - 2 years now, and it is still just as fun (if not more) as it was when I started. Rust has many great features which makes it different from others, and all of them have their own pros and cons. However, there are some features in Rust which I miss when writing code in other languages.&lt;/p&gt;

&lt;p&gt;In this post, I'll be talking about two such features : One which you might know and be familiar with, and one which you might not know directly. I think both of them are valuable not only for better code, but even from a developer's perspective, and helps me to think clearly and write better code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error Management
&lt;/h2&gt;

&lt;p&gt;Now, I don't mean to say other languages do not have error handling. Its just that the way Rust does error handling has an elegance and simplicity , which I miss in other languages.&lt;/p&gt;

&lt;p&gt;I truly feel that Rust has done a great job with error handling. Even if &lt;a href="https://steveklabnik.com/writing/you-re-probably-learning-a-technology-in-its-seventh-season-not-its-pilot" rel="noopener noreferrer"&gt;not everyone might agree with the particular way it is done&lt;/a&gt; , I still feel it is one of the best error handling ideology that I have seen.&lt;/p&gt;

&lt;p&gt;Error handling in Rust gets divided into two distinct types of errors :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recoverable/ "true" errors : This is the most common one, which is almost entirely supported by &lt;code&gt;Result&lt;/code&gt; enum. These kinds of errors are something that you know might occur, and want to bubble up, or display to users.&lt;/li&gt;
&lt;li&gt;Non-recoverable / "exceptions" : These are signified by &lt;code&gt;panic&lt;/code&gt;s and &lt;code&gt;unwrap&lt;/code&gt;s. These signify that some invariant is broken; or that some basic assumption which should have been true, is actually false. In such cases there is really no point on continuing, and crashing is a better option.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of other languages do not separate these two kinds.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java, Python, JS only have &lt;code&gt;Exception&lt;/code&gt;s, a single mechanism which must be used to indicate both ; or we must have an &lt;code&gt;error:true/false&lt;/code&gt; field in all return types, and caller must check before using the returned value.&lt;/li&gt;
&lt;li&gt;C has &lt;code&gt;errno&lt;/code&gt; . To start with, it is a global variable for the whole code, and there is not much support to attach custom error messages without doing something similar as returning an &lt;code&gt;enum&lt;/code&gt; with error and data components.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt; : As some have pointed out in the comments,  Java and scala has an &lt;code&gt;Either&lt;/code&gt; type somewhat equivalent to &lt;code&gt;Result&lt;/code&gt; in Rust, and Go has error wrapping.  I missed them originally when writing, as I do not work with these languages much.&lt;/p&gt;




&lt;p&gt;Rust separating these two kinds allows me to think on what possible errors might occur - all known possible errors are declared upfront along with the return type, and only unexpected errors can cause crashes at runtime.&lt;/p&gt;

&lt;p&gt;Apart from that, I think Rust has beautiful syntax support, which makes it feel that error handling was a first-class thing, not just an after thought.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;?&lt;/code&gt; operator allows bubbling up errors in a clean way. No need to have only a top level catch, or do a catch-check-rethrow.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;unwrap()&lt;/code&gt; calls indicate what are our base assumptions for the code.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;unwrap_or&lt;/code&gt; and similar APIs on &lt;code&gt;Result&lt;/code&gt; allows setting a default / sane fallback in clean way.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because of such nice support, there are quite a few libraries which build on top of this and allows us to have more good things :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/anyhow" rel="noopener noreferrer"&gt;anyhow&lt;/a&gt; is one of the GOAT crates, allowing to bubble up many error types from a single function, and attach context to errors&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/eyre" rel="noopener noreferrer"&gt;eyre&lt;/a&gt; is a fork-extention of annyhow, and provides way to derive error types and reports for structs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;consider the following which uses anyhow crate :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;'function&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;errored&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.with_context&lt;/span&gt;&lt;span class="p"&gt;(||&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;'function&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;errored&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;param1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;'&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result1&lt;/span&gt;&lt;span class="nf"&gt;.update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;'update&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;result2&lt;/span&gt; &lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way we can attach context to each individual error at each step, without having to add any additional piece of code. To the best of my knowledge, there is no straightforward way of doing something similar in other languages.&lt;/p&gt;

&lt;p&gt;Consider doing similar in JS : if we use Exceptions to indicate errors, we either have to wrap all three in single try-catch and lose the granularity of context ; or have a try-catch for each, attach context to the caught error and re-throw from the catch block. This quickly gets out of hand as the code grows and there are more possible points for errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  #[must_use] Annotation
&lt;/h2&gt;

&lt;p&gt;Even though &lt;code&gt;#[must_use]&lt;/code&gt; is not directly a part of Rust syntax / language itself, I think this is one of its underrated parts.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#[must_use]&lt;/code&gt; does not modify the code's output in any way, however it provides a lint which can be very helpful for catching some easy-to-miss bugs.&lt;/p&gt;

&lt;p&gt;When we annotate any type with this, values of those types must be used. Consider the &lt;code&gt;Result&lt;/code&gt; type which is annotated with &lt;code&gt;#[must_use]&lt;/code&gt;. If we call a function which returns a result, but do not use / capture that return value :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;result_returning_function&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we will get a compiler warning saying&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;warning: unused &lt;span class="sb"&gt;`&lt;/span&gt;Result&lt;span class="sb"&gt;`&lt;/span&gt; that must be used
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thus, we can make sure all &lt;code&gt;Result&lt;/code&gt;s are acknowledged, and we do not accidentally miss any potential error.&lt;/p&gt;

&lt;p&gt;This also beautifully integrates with Futures. As Futures must be polled for them to resolve, if we create a future, but do not await it, we get a warning such as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;warning: unused implementer of &lt;span class="sb"&gt;`&lt;/span&gt;Future&lt;span class="sb"&gt;`&lt;/span&gt; that must be used
...
note: futures &lt;span class="k"&gt;do &lt;/span&gt;nothing unless you &lt;span class="sb"&gt;`&lt;/span&gt;.await&lt;span class="sb"&gt;`&lt;/span&gt; or poll them
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally Rust stdlib itself uses this to warn us of &lt;a href="https://std-dev-guide.rust-lang.org/code-considerations/design/must-use.html" rel="noopener noreferrer"&gt;some gotchas&lt;/a&gt;. For example &lt;code&gt;wrapping_add&lt;/code&gt; and such methods are directly called on values, but do not modify those values, but instead return a new value. One can easily forget this, and assume that the original value is modified. This warning prevents us to miss it easily.&lt;/p&gt;

&lt;p&gt;As far as I know, no other language has anything similar, even considering external linters. I miss this specifically in JS, where there are no ways to ensure async functions are (eventually) awaited when called. Because of that, I sometimes miss awaiting a single async function call in async context, and that single function runs asynchronously, while rest do not.&lt;/p&gt;

&lt;p&gt;Having the &lt;code&gt;#[must_use]&lt;/code&gt; or equivalent would make catching such errors much easier.&lt;/p&gt;




&lt;p&gt;Thank you for reading! Are there any other features of Rust you miss when coding in other languages? Or Any features of other languages that you miss when coding in Rust? Feel free to let me know your thoughts in the comments :)&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Announcing Youki 0.0.4 🎉🎉🎉</title>
      <dc:creator>YJDoc2</dc:creator>
      <pubDate>Wed, 14 Dec 2022 16:07:33 +0000</pubDate>
      <link>https://dev.to/yjdoc2/announcing-youki-040-ocn</link>
      <guid>https://dev.to/yjdoc2/announcing-youki-040-ocn</guid>
      <description>&lt;p&gt;Hello everyone!&lt;/p&gt;

&lt;p&gt;For about a year now, I have been doing some open source contributions to a great project called &lt;code&gt;Youki&lt;/code&gt;. It is a low level container runtime, written in Rust language, which aims to be similar to existing &lt;code&gt;runc&lt;/code&gt; or &lt;code&gt;crun&lt;/code&gt; projects, with its own advantages. It has been immense fun to contribute, and I have learnt a lot while doing this, right from writing docs, figuring out stuff in a complex code base to Linux internals such as namespaces, cgroups, and processes.&lt;/p&gt;

&lt;p&gt;Today, we are announcing version 0.0.4 of Youki.&lt;/p&gt;

&lt;h2&gt;
  
  
  In this release
&lt;/h2&gt;

&lt;p&gt;last release of v0.0.3 was done in April, and this release brings some pretty exciting updates to Youki :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now Youki passes all of the contained integration tests, which means it can be used a runtime with containerd like runc or crun&lt;/li&gt;
&lt;li&gt;Adds support for WasmEdge, which is one of the fastest WASM runtimes&lt;/li&gt;
&lt;li&gt;And Many More!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Full changelog + release notes can be seen here : &lt;a href="https://github.com/containers/youki/releases/tag/v0.0.4" rel="noopener noreferrer"&gt;https://github.com/containers/youki/releases/tag/v0.0.4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks to everyone who &lt;a href="https://github.com/containers/youki/graphs/contributors" rel="noopener noreferrer"&gt;contributed&lt;/a&gt; and helped us achieve this! &lt;/p&gt;

&lt;p&gt;Personally, I'd also like to especially mention &lt;a href="//github.com/utam0k/"&gt;utam0k&lt;/a&gt; and &lt;a href="//github.com/Furisto/"&gt;Furisto&lt;/a&gt; who helped me a lot!&lt;/p&gt;

&lt;p&gt;Check out Youki  at its github Repo :&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/youki-dev" rel="noopener noreferrer"&gt;
        youki-dev
      &lt;/a&gt; / &lt;a href="https://github.com/youki-dev/youki" rel="noopener noreferrer"&gt;
        youki
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A container runtime written in Rust
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;youki: A container runtime in Rust&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://discord.gg/zHnyXKSQFD" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/11361a6d4d3ff84398e98638c45f84a51730832f88a3ad0c0bc09fbc5d54fb5e/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f3834393934333030303737303431323537352e7376673f6c6f676f3d646973636f7264" alt="Discord"&gt;&lt;/a&gt;
&lt;a href="https://github.com/containers/youki/graphs/contributors" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0ae797c583b6fd2a2ac71dc4bc32b93b8fa4d5adcd79d836f08a7e0cbe7abeb0/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6e7472696275746f72732f636f6e7461696e6572732f796f756b69" alt="GitHub contributors"&gt;&lt;/a&gt;
&lt;a href="https://github.com/containers/youki/actions" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/containers/youki/actions/workflows/basic.yml/badge.svg?branch=main" alt="Github CI"&gt;&lt;/a&gt;
&lt;a href="https://codecov.io/gh/containers/youki" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/de68fdede6039c96b17f577ec7a153d6d618acdb066ec6f5ec4b9b2daf0cc9a4/68747470733a2f2f636f6465636f762e696f2f67682f636f6e7461696e6572732f796f756b692f6272616e63682f6d61696e2f67726170682f62616467652e737667" alt="codecov"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/youki-dev/youkidocs/youki.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fyouki-dev%2Fyoukidocs%2Fyouki.png" width="450"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;youki&lt;/strong&gt; is an implementation of the &lt;a href="https://github.com/opencontainers/runtime-spec" rel="noopener noreferrer"&gt;OCI runtime-spec&lt;/a&gt; in Rust, similar to &lt;a href="https://github.com/opencontainers/runc" rel="noopener noreferrer"&gt;runc&lt;/a&gt;.&lt;br&gt;
Your ideas are welcome &lt;a href="https://github.com/containers/youki/issues/10" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🏷️ About the name&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;youki is pronounced as /joʊki/ or yoh-key
youki is named after the Japanese word 'youki', which means 'a container'. In Japanese language, youki also means 'cheerful', 'merry', or 'hilarious'.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🚀 Quick Start&lt;/h1&gt;

&lt;/div&gt;
&lt;div class="markdown-alert markdown-alert-tip"&gt;
&lt;p class="markdown-alert-title"&gt;Tip&lt;/p&gt;
&lt;p&gt;You can immediately set up your environment with youki on GitHub Codespaces and try it out.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://codespaces.new/containers/youki?quickstart=1" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://github.com/codespaces/badge.svg" alt="Open in GitHub Codespaces"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight highlight-text-shell-session notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;$ &lt;span class="pl-s1"&gt;just build&lt;/span&gt;
$ &lt;span class="pl-s1"&gt;docker run --runtime youki hello-world&lt;/span&gt;
$ &lt;span class="pl-s1"&gt;sudo podman run --cgroup-manager=cgroupfs --runtime /workspaces/youki/youki hello-world&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://youki-dev.github.io/youki/user/basic_setup.html#quick-install" rel="nofollow noopener noreferrer"&gt;User Documentation&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🎯 Motivation&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;Here is why we are writing a new container runtime in Rust.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Rust is one of the best languages to implement the oci-runtime spec. Many very nice container tools are currently written in Go. However, the container runtime requires the use of system calls, which requires a bit of special…&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/youki-dev/youki" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;We also have a nice documentation up at &lt;a href="https://containers.github.io/youki/" rel="noopener noreferrer"&gt;https://containers.github.io/youki/&lt;/a&gt; for both users and developers, come take a look!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>opensource</category>
      <category>devops</category>
      <category>tooling</category>
    </item>
    <item>
      <title>What is stopping you from learning C?</title>
      <dc:creator>YJDoc2</dc:creator>
      <pubDate>Fri, 02 Dec 2022 15:34:40 +0000</pubDate>
      <link>https://dev.to/yjdoc2/what-is-stopping-you-from-learning-c-272k</link>
      <guid>https://dev.to/yjdoc2/what-is-stopping-you-from-learning-c-272k</guid>
      <description>&lt;p&gt;Hello Everyone! Today I have a question for you -&amp;gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  C
&lt;/h2&gt;

&lt;p&gt;I like C. I'd go even as far as saying C is one of the most beautiful languages out there. Yes, you can shoot yourself in the foot easily, and Yes, it is tedious to do complex stuff in it, but those are good reasons why one might not want to use it for stuff, not why you shouldn't want to learn C.&lt;/p&gt;

&lt;p&gt;C is one of the minimal languages, with fairly simple syntax, and if there is anything you want to do using a computer, you can do it using C 99.9% of the times&lt;sup id="fnref1"&gt;1&lt;/sup&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  No, You should not use C for everything.
&lt;/h2&gt;

&lt;p&gt;I like C. But I will not suggest using it for everything, especially when today there are many languages, each having their own advantages and disadvantages for any particular task :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing a web application? Hard to beat JS or Elm&lt;/li&gt;
&lt;li&gt;Want to check out something quickly, or do data-wrangling? Python might be a good fit&lt;/li&gt;
&lt;li&gt;Want to write a very stable application with helpful compiler and sanity checks? Rust.&lt;/li&gt;
&lt;li&gt;Maths and graphs? R, Matlab, Python+matplotlib - take your pick&lt;/li&gt;
&lt;li&gt;Want to effectively communicate with others without misunderstandings? maybe use ???&lt;sup id="fnref2"&gt;2&lt;/sup&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But anyways - I will not suggest using C today for doing everything, especially when there are better alternatives. But again, this is an argument for not using it, not for not learning it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then why to learn C
&lt;/h2&gt;

&lt;p&gt;You might be getting a feeling that I like C. It is correct.&lt;/p&gt;

&lt;p&gt;With the above examples, why would I suggest learning C anymore? It does not seem to be used that much, it is not that easy to write stuff in, then why?&lt;/p&gt;

&lt;p&gt;Well, C is still used a lot, only we don't really get to &lt;em&gt;see&lt;/em&gt; a lot of it. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Most of the Operating systems that are used today - Linux, Microsoft, MacOS, Android; are written mostly in C, with a dash of assembly and hint of other languages. So whatever you are reading/listening this on, you can thank C for making it work&lt;/li&gt;
&lt;li&gt;Embedded systems still hail C. From dials on your devices, smart appliances and whatnot, C still rules the embedded world with the help of assembly. So next time you use your digital dial on something, you can thank C for making it work.&lt;/li&gt;
&lt;li&gt;Almost all of the drivers needed to make hardware work with your machine uses primarily C. There might be other languages thrown in the mix, and there might be some languages trying to take its thrown, but C still stands supreme here. So when you get a new graphics card, or plug-in a mouse and &lt;code&gt;it-just-works(TM)&lt;/code&gt;, You can thank C&lt;sup id="fnref3"&gt;3&lt;/sup&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  But you say you are never going to do that?
&lt;/h2&gt;

&lt;p&gt;Being a person who is interested in Systems and OSs, I like C. And those who are reading and also interested in it might already be interested in C.&lt;/p&gt;

&lt;p&gt;But the &lt;em&gt;small number&lt;/em&gt;&lt;sup id="fnref4"&gt;4&lt;/sup&gt; of other people who do stuff like web-dev, might never want to deal with it, so why should they bother learning it?&lt;/p&gt;

&lt;p&gt;Well, unlike the myth,  C might not be the "closest" language to the hardware anymore ; but it still is one of the most down-to-earth&lt;sup id="fnref5"&gt;5&lt;/sup&gt; languages out there. You will still get a lot more understanding of how  your computer works, and how the JS interpreter and browser that runs you code and displays your site works under the hood.&lt;/p&gt;

&lt;p&gt;It is also a strictly typed language, so you will get a feel of keeping in mind what type your data is when passing around. It can still be useful as a sub-conscious check when using duck-typed languages, to avoid &lt;code&gt;req.redirect is not a function&lt;/code&gt; or &lt;code&gt;myAwesomeVar.myAwesomeProperty is undefined&lt;/code&gt; errors. Don't they just hurt when your code is deployed and crashes, just because that one particular path of execution was missed when you were testing it?&lt;/p&gt;

&lt;h2&gt;
  
  
  So Should you learn C?
&lt;/h2&gt;

&lt;p&gt;Me, liking C , will say yes. No you should not use &lt;em&gt;Only&lt;/em&gt; C and No you should not use C everywhere, but I feel it is worth the effort to learn C and do some small projects in it. It can be a lot of fun and help you understand a lot more about the immensely powerful machines&lt;sup id="fnref6"&gt;6&lt;/sup&gt; that we hold in our hands.&lt;/p&gt;

&lt;p&gt;But it might not be easy to do so. Maybe you have tried and stopped, maybe you tried really hard and just couldn't. And I'm interested to know what was it. What is stopping you from learning C.&lt;/p&gt;

&lt;h2&gt;
  
  
  What stopped me from learning C
&lt;/h2&gt;

&lt;p&gt;Before I started really liking C, there was a time where C felt really confusing, and I also didn't really understand why I should learn C.&lt;/p&gt;

&lt;p&gt;For me the reason that was stopping me was the concept of pointers. It took me about three tries with three different approaches to it, before I could finally understand what are pointers and why they are useful.&lt;/p&gt;

&lt;p&gt;Funnily enough, the way I finally understood them had hardly anything to do with learning C : I was reading a book on Linux and its features and stuff, and it had a lot of C programs in it as examples of Linux programming. I didn't understand half the things I read about Linux then, but it helped me to get my concept of pointers cleared.&lt;/p&gt;

&lt;p&gt;And so now I want to help others as I can. I am thinking of writing a book-as-blog&lt;sup id="fnref7"&gt;7&lt;/sup&gt; in which I intend to start from the very basic concepts, and try to write what &lt;em&gt;I&lt;/em&gt; know about C. And for that to be useful, I need to know what do you find difficult when learning about C.&lt;/p&gt;

&lt;p&gt;So please help me, and tell me : What is stopping you from learning C? It can be as simple as you never wanted to, or you never really knew why you should, or maybe a concept that you felt was difficult enough to stop learning C. Those who have learnt C and enjoy it, please let me know what resources did you use? Did you find anything particularly good that helped you learn C?&lt;/p&gt;

&lt;p&gt;Looking forward to your comments.&lt;/p&gt;

&lt;p&gt;Oh, and in case you didn't notice, I really like C.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;




&lt;p&gt;Cover image credit : By Rezonansowy - This file was derived from: The C Programming Language, First Edition Cover (2).svg, Public Domain, &lt;a href="https://commons.wikimedia.org/w/index.php?curid=29423032" rel="noopener noreferrer"&gt;https://commons.wikimedia.org/w/index.php?curid=29423032&lt;/a&gt;&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Rest 0.1% is when you are dealing with hardware at its bare-most level, eg. bootloaders ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;This probably is NP-hard, bordering on unsolvable ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;And the people who do the tedious task of writing and distributing those drivers too. Those also deserve more recognition and love! ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;See proof at &lt;a href="https://dev.to/derlin/devto-is-for-webdevs-and-beginners-i-have-data-to-prove-it-54c4"&gt;https://dev.to/derlin/devto-is-for-webdevs-and-beginners-i-have-data-to-prove-it-54c4&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn5"&gt;
&lt;p&gt;Read down-to-&lt;em&gt;silicon&lt;/em&gt; 🥁 ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn6"&gt;
&lt;p&gt;&lt;a href="https://xkcd.com/676/" rel="noopener noreferrer"&gt;https://xkcd.com/676/&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn7"&gt;
&lt;p&gt;Sometimes also referred to as blog-as-book ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>discuss</category>
      <category>c</category>
      <category>programming</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>Introducing PCB-rs : Making it easier to write hardware</title>
      <dc:creator>YJDoc2</dc:creator>
      <pubDate>Fri, 08 Apr 2022 14:20:04 +0000</pubDate>
      <link>https://dev.to/yjdoc2/introducing-pcb-rs-making-it-easier-to-write-hardware-397m</link>
      <guid>https://dev.to/yjdoc2/introducing-pcb-rs-making-it-easier-to-write-hardware-397m</guid>
      <description>&lt;p&gt;Remember the &lt;a href="https://dev.to/yjdoc2/what-is-keeping-you-from-dabbling-in-writing-hardware--1k1e"&gt;post I wrote about 2 months ago&lt;/a&gt; ? Asking why you don't write much hardware?&lt;br&gt;
In it I said I was writing a library to make it easier. Well, I have completed the initial release version of it 🎉 🎉 🎉&lt;/p&gt;



&lt;p&gt;Quick note : I don't usually ask this, but please share this article, or directly the library on your socials or such! I have spent quite some time on developing it, and I really want people who can benefit from this to use this. Your share might help this reach someone who needs it. Thank you!&lt;/p&gt;


&lt;h2&gt;
  
  
  So, what is it?
&lt;/h2&gt;

&lt;p&gt;Well, I'm happy to share with you : &lt;code&gt;pcb-rs&lt;/code&gt; ! This is a library which will make it much easier for you to write hardware components, and simulate them. It does this by giving you two proc-macros, which you can use with your run-of-the-mill &lt;code&gt;struct&lt;/code&gt;s and it will generate the interface implementation for you!&lt;/p&gt;
&lt;h2&gt;
  
  
  Why ???
&lt;/h2&gt;

&lt;p&gt;Because I want to make it easier for people who wish to explore hardware to do so. This does not aim to be the perfect and most-accurate-simulation ever ; or try to replace VHDL, (because it does not). This aims to be a rung in the ladder from high-level programming language to hardware level. That way those who are just starting to explore it, will have to jump a little less height : they can still work in comfort of Rust, but can have the taste of things that one has to consider when designing hardware.&lt;/p&gt;

&lt;p&gt;It is choose-your-own-difficulty hardware design!&lt;/p&gt;
&lt;h2&gt;
  
  
  Show, don't tell
&lt;/h2&gt;

&lt;p&gt;Here I'm showing how you can write a simple 256-byte RAM as a hardware component using my library :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pcb_rs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Chip&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Chip)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Memory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;#[pin(input)]&lt;/span&gt;
    &lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nd"&gt;#[pin(io,&lt;/span&gt; &lt;span class="nd"&gt;io_latch)]&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nd"&gt;#[pin(input)]&lt;/span&gt;
    &lt;span class="n"&gt;is_active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nd"&gt;#[pin(input)]&lt;/span&gt;
    &lt;span class="n"&gt;is_read&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="n"&gt;io_latch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Chip&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Memory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;tick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.is_active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.io_latch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.is_read&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.addr&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.mem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.io_latch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.addr&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.mem&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here the &lt;code&gt;derive(Chip)&lt;/code&gt; is my prco-macro which automatically implements the required traits for your chip, and you just have to write &lt;code&gt;impl Chip&lt;/code&gt; which defines the processing logic of your chip.&lt;/p&gt;

&lt;p&gt;Thus in about ~33 lines, we have a working RAM. This is also modular - it can be used with other components, such as CPU 🎉 🎉 And pcb-rs also provides another macro for that :&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;pcb!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PCB&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;chip&lt;/span&gt; &lt;span class="n"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;chip&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nn"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;addr_bus&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nn"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nn"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;data_bus&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nn"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nn"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;mem_active&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nn"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;is_active&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nn"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;read_mem&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nn"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;is_read&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Yep. That's it. That's all you have to define to interface a CPU and the RAM. the &lt;code&gt;pcb!&lt;/code&gt; macro will parse this, derive the logic for validating the chips given to it , derive the logic to verify the pin connection, derive the logic for passing values from one chip to another, and write the builer and pcb struct.&lt;br&gt;
Now to actually place the RAM and CPU pins in it:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Memory&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;cpu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;CPU&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nn"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;PCBBuilder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;PCBBuilder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="nf"&gt;.add_chip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cpu"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.add_chip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mem"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;pcb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;PCB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="nf"&gt;.build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;pcb&lt;/span&gt;&lt;span class="nf"&gt;.tick&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This will place the chips in the builder, validate that correct chips have been placed, and give you the PCB struct, which contains all the running logic after calling build. The PCB itself will have the &lt;code&gt;tick()&lt;/code&gt; method, which will run your chips.&lt;/p&gt;

&lt;p&gt;And you know what, this itself is modular! You can use such chips as part of some other PCB, and so on 🎉 🎉&lt;/p&gt;
&lt;h2&gt;
  
  
  Wait, you're telling me this is easier?
&lt;/h2&gt;

&lt;p&gt;Well, yeah! This will allow you to write Hardware components from comfort of Rust, before you get into something more complex as VHDL. Also you have to write just the struct and annotate what members you want to use as pins, and then write the processing logic for the chip. Everything else is derived by the macro for you. &lt;/p&gt;

&lt;p&gt;Same for pcb, you just have to define the chips, connections and what pins you want to expose to others, rest, including the actual struct, will be derived by the macro.&lt;/p&gt;
&lt;h2&gt;
  
  
  Ok, show me more
&lt;/h2&gt;

&lt;p&gt;I know this is pretty different that what many of you might be usually doing. So, as examples, I have written several components that range from pretty basic to a bit complex.&lt;/p&gt;

&lt;p&gt;You know what's more? As Rust can compile to WASM, I have also done that and have made a web interface for the examples. You can run them directly from your browsers. Check it out at &lt;a href="https://yjdoc2.github.io/pcb-rs-examples/" rel="noopener noreferrer"&gt;https://yjdoc2.github.io/pcb-rs-examples/&lt;/a&gt;.&lt;br&gt;
Currently the examples consist of :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic gates such as Not, And, Or, Xor &lt;a href="https://en.wikipedia.org/wiki/Logic_gate" rel="noopener noreferrer"&gt;wikipedia&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Ripple carry adder &lt;a href="https://en.wikipedia.org/wiki/Adder_(electronics)#Ripple-carry_adder" rel="noopener noreferrer"&gt;wikipedia&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Look ahead Carry adder &lt;a href="https://en.wikipedia.org/wiki/Carry-lookahead_adder" rel="noopener noreferrer"&gt;wikipedia&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;SR, D, T, JK Latches &lt;a href="https://en.wikipedia.org/wiki/Flip-flop_(electronics)" rel="noopener noreferrer"&gt;wikipedia&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Straight and Twisted Ring counters &lt;a href="https://en.wikipedia.org/wiki/Ring_counter" rel="noopener noreferrer"&gt;wikipedia&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;CPU and PCB example which I showed above&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can try all these right in your browser, at &lt;a href="https://yjdoc2.github.io/pcb-rs-examples/" rel="noopener noreferrer"&gt;https://yjdoc2.github.io/pcb-rs-examples/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I made these particular examples, as these are usually a part of basic hardware/electronics course, so these will be a good taste of how pcb-rs library can be used for that.&lt;/p&gt;
&lt;h3&gt;
  
  
  Links, Links and Links
&lt;/h3&gt;

&lt;p&gt;So,&lt;br&gt;
The library :&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/YJDoc2" rel="noopener noreferrer"&gt;
        YJDoc2
      &lt;/a&gt; / &lt;a href="https://github.com/YJDoc2/pcb-rs" rel="noopener noreferrer"&gt;
        pcb-rs
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A library to easily write software emulated hardware
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Pcb-rs&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;A library to easily wite Software Emulated Hardware&lt;/p&gt;




&lt;p&gt;This library provides two macros &lt;code&gt;Chip&lt;/code&gt; and &lt;code&gt;pcb&lt;/code&gt; which can be used to write software emulated hardware components. &lt;code&gt;Chip&lt;/code&gt; is a derive macro which can be used on structs to automatically implement the necessary interfaces for the struct to be treated as a Hardware Chip, and you only need to implement the tick function which will be called on each clock cycle to run the logic of your chip. &lt;code&gt;pcb&lt;/code&gt; macro is used to define a PCB , where you can connect multiple chips, and it will manage connecting pins of chips, verifying the connections and passing the data on the connected chip.&lt;/p&gt;

&lt;p&gt;One of the aims of this library is modularity and reusability, thus the pcb created can be further used as chips in some other pcb ans so on.&lt;/p&gt;

&lt;p&gt;There are some finer points to be noted when creating…&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/YJDoc2/pcb-rs" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;&lt;br&gt;
The examples :&lt;br&gt;

&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/YJDoc2" rel="noopener noreferrer"&gt;
        YJDoc2
      &lt;/a&gt; / &lt;a href="https://github.com/YJDoc2/pcb-rs-examples" rel="noopener noreferrer"&gt;
        pcb-rs-examples
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Repository containing examples of usage of pcb-rs
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;PCB-RS Examples&lt;/h1&gt;
&lt;/div&gt;




&lt;p&gt;This repository contains examples to demonstrate use of &lt;a href="https://www.github.com/YJDoc2/pcb-rs" rel="noopener noreferrer"&gt;pcb-rs&lt;/a&gt;. To see more information about what is pcb-rs, the reasoning behind it, and basic syntax and examples, visit its repository at &lt;a href="https://www.github.com/YJDoc2/pcb-rs" rel="noopener noreferrer"&gt;https://www.github.com/YJDoc2/pcb-rs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This repository contains various examples on how to write components, as well as how to reuse components from other libraries to create a composite component. Each of the directories contain their own readme describing the that particular example.&lt;/p&gt;

&lt;p&gt;The web version of these examples is hosted at &lt;a href="https://yjdoc2.github.io/pcb-rs-examples/" rel="nofollow noopener noreferrer"&gt;yjdoc2.github.io/pcb-rs-examples/&lt;/a&gt;, so you can try them right in your browser without needing to install anything, as well as show the possibilities with this library and WASM for making such electronics related tools and simulations.&lt;/p&gt;




&lt;p&gt;Various directories in this repo contain different examples, and their details are explained in their own readmes in that directory. Currently this repo contains following directories :&lt;/p&gt;


&lt;ul&gt;

&lt;li&gt;

&lt;a href="https://github.com/YJDoc2/pcb-rs-examples./basic-gates/" rel="noopener noreferrer"&gt;Basic Gates&lt;/a&gt; : This contains basic…&lt;/li&gt;

&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/YJDoc2/pcb-rs-examples" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;&lt;br&gt;
The Web interface for the examples : &lt;a href="https://yjdoc2.github.io/pcb-rs-examples/" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://yjdoc2.github.io/pcb-rs-examples/" rel="noopener noreferrer"&gt;https://yjdoc2.github.io/pcb-rs-examples/&lt;/a&gt;.

&lt;h2&gt;
  
  
  And ...?
&lt;/h2&gt;

&lt;p&gt;Go Check It Out!!! Try it out in your own projects, share the projects and let me know how are you using it!&lt;/p&gt;

&lt;p&gt;And as I said in the start, I don't usually ask this, but please consider sharing this. I really want this to help people who want to get into hardware. Your share will help this reach more people. &lt;/p&gt;

&lt;p&gt;Also if you think this is interesting, consider starring it on GitHub. That might also help getting this more attention.&lt;/p&gt;

&lt;p&gt;Let me know in comments your thoughts and reviews for this.&lt;/p&gt;

&lt;p&gt;Thanks a lot for reading! &lt;/p&gt;




&lt;p&gt;Note : header image is taken from google images search, and is not mine.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>showdev</category>
      <category>beginners</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>What is keeping you from dabbling in writing Hardware ?</title>
      <dc:creator>YJDoc2</dc:creator>
      <pubDate>Sat, 19 Feb 2022 14:32:45 +0000</pubDate>
      <link>https://dev.to/yjdoc2/what-is-keeping-you-from-dabbling-in-writing-hardware--1k1e</link>
      <guid>https://dev.to/yjdoc2/what-is-keeping-you-from-dabbling-in-writing-hardware--1k1e</guid>
      <description>&lt;p&gt;Let's face it, if you are writing any program, in any language : you need hardware to run it.&lt;/p&gt;

&lt;p&gt;If you write C / C++ / Rust code it will compile to binary which will execute inside you processor (eventually) and if you use python / JS it will run on top of their interpreters, which themselves run on the hardware. One way or other you will have to use hardware to execute your code. I hope we can agree on this 😉 😉&lt;/p&gt;

&lt;p&gt;Hardware such as CPU does some really amazing things , latest CPUs have pipelined processing, so that they can run multiple instructions at the same time, and also logic to detect if the next instructions can run at the same time or not. They have several 128 bit-and-more registers which can process floating numbers and strings crazy fast, parallely and with various options : Do you know there is an instruction in x86 instruction set ( one used by common Intel and AMD CPUs) that can check if a substring is present or not in given string?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3e7jbvblvv4uzvjaqyh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3e7jbvblvv4uzvjaqyh.jpg" alt="a complex but processor board" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I agree that at the beginning it can be hard, even outright scary to get into such low level of systems, where everything is in binary and you have to take into consideration the things that you didn't know existed. But as with any other programming / coding / computer related stuff, I think it can get more manageable, if not easy, if one works with it more. &lt;/p&gt;

&lt;p&gt;Think about the first website or app or any project that you made, and how complex or technical it seemed at first, and how hard it seems after having done it several times after. The more you play with it, the more you try and make mistakes, I feel the better you get at it.&lt;/p&gt;

&lt;p&gt;So, what is stopping you from getting into something so cool as hardware ?&lt;/p&gt;

&lt;p&gt;In my case :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To buy and work with actual Hardware, like Raspberry Pi, involves some cost, and even then I'm still working on an API abstraction of some libraries (usually)&lt;/li&gt;
&lt;li&gt;For designing actual hardware at the low level, current options usually involve VHDL or Verilog like softwares, and it can get pretty complex pretty soon, even to implement something very simple. Don't get me wrong, those s/w are pretty amazing, they can &lt;strong&gt;&lt;em&gt;Optimize&lt;/em&gt;&lt;/strong&gt; the circuits you wrote,and can be used to actually synthesize stuff that can be etched onto FPGAs , Which is pretty cool! But for a beginner who want to write few chips, the overhead can be tedious.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, mainly because of the point 2, I am currently working on a library in Rust which will make it easier to write s/w emulated h/w in Rust. The complete logic of your chip will be in Rust, you can access files and stuff if you want, and do anything that Rust can do. The way I'm thinking, it will be as simple as writing a struct/class, annotating which pins are input, output and a function to operate what the chip will actually do based on the values of those pins.&lt;/p&gt;

&lt;p&gt;Now this won't help you write Intel Pentium in 100 lines of code. Even emulators for Intel 8086, which was released in 1987, take about 2000-5000 lines of code (I would know, I have &lt;a href="https://dev.to/yjdoc2/we-made-8086-emulator-in-rust-and-integrated-it-with-react-using-wasm-742"&gt;written one&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;That said, this will allow you to ignore how to connect pins of various chips or how to write interface to connect chips and allow you to focus on the logic of the chip, like how 4-bit binary adders add two numbers or how ring counters actually count, or  how a CPU actually reads the data from RAM and so on. This also aims to make them sharable so you can take RAM someone else wrote and interface it with you CPU,  just like you would use different modules or packages for a project.&lt;/p&gt;

&lt;p&gt;Even though I am writing it in Rust, the logic behind it does not depend on Rust, so one can easily do the same in Python or JS, and maybe even use Rust components with them.&lt;/p&gt;

&lt;p&gt;I will share it once the things are done, but in the meantime I would like to know what is keeping &lt;strong&gt;&lt;em&gt;you&lt;/em&gt;&lt;/strong&gt; form dabbling in writing s/w emulated h/w. Maybe I can add features which will solve your issues too. Let me know in the comments!&lt;/p&gt;




&lt;p&gt;PS : if you want to know when I publish the library, follow me 😉 you can unfollow after I publish it , I won't mind 😄&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

&lt;p&gt;Note : all images are taken from google images search, and are not mine.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>rust</category>
      <category>beginners</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>A Rust macro which will derive Bytecode for you</title>
      <dc:creator>YJDoc2</dc:creator>
      <pubDate>Tue, 04 Jan 2022 11:43:40 +0000</pubDate>
      <link>https://dev.to/yjdoc2/a-rust-macro-which-will-derive-bytecode-for-you-556n</link>
      <guid>https://dev.to/yjdoc2/a-rust-macro-which-will-derive-bytecode-for-you-556n</guid>
      <description>&lt;p&gt;Hello!&lt;/p&gt;

&lt;p&gt;I made a Rust proc-macro which will compile and parse your enums and structs to and from a bytecode for you!!!&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/YJDoc2" rel="noopener noreferrer"&gt;
        YJDoc2
      &lt;/a&gt; / &lt;a href="https://github.com/YJDoc2/Bytecode" rel="noopener noreferrer"&gt;
        Bytecode
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A Rust proc-macro crate which derives functions to compile and parse back enums and structs to and from a bytecode representation
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Check it out and star it if you think it is interesting!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;Consider you are writing a VM, and need a bytecode representation for your opcodes, to store it in the VM's memory. You might consider something like this :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Register&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;AX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;BX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Opcode&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Nop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Hlt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Register&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;Register&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;AddI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Register&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you try to write functions to compile and parse these two enums to a simple bytecode, it would be something like this :&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Register&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nn"&gt;Register&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;AX&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="nn"&gt;Register&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BX&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="k"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]{&lt;/span&gt;
            &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Register&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;AX&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Register&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BX&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="o"&gt;...&lt;/span&gt;
            &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid opcode"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Opcode&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nn"&gt;Opcode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Nop&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="nn"&gt;Opcode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Hlt&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="nn"&gt;Opcode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;r2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_capacity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="nf"&gt;.extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;r1&lt;/span&gt;&lt;span class="nf"&gt;.compile&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="nf"&gt;.extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;r2&lt;/span&gt;&lt;span class="nf"&gt;.compile&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                &lt;span class="n"&gt;v&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nn"&gt;Opcode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;AddI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_capacity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="nf"&gt;.extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;r1&lt;/span&gt;&lt;span class="nf"&gt;.compile&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="nf"&gt;.extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="nf"&gt;.to_le_bytes&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                &lt;span class="n"&gt;v&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="k"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]{&lt;/span&gt;
            &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Opcode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Nop&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Opcode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Hlt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Register&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="o"&gt;...&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;...&lt;/span&gt;
            &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid opcode"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Even for the two instructions I have shown, this is pretty long, tedious and boring. &lt;/p&gt;

&lt;p&gt;And now consider doing this for at least 25 to upto 100-ish opcodes, as you might need. 😟 😰 &lt;/p&gt;

&lt;p&gt;And now consider you want to remove a variant or add a variant in the middle of an enum 😰 😱&lt;/p&gt;

&lt;p&gt;You will need to shift all the values accordingly, manually. &lt;br&gt;
Not Fun.&lt;/p&gt;

&lt;p&gt;The macro will do this for you, and let you concentrate on implementing your VM.&lt;br&gt;
Fun. (hopefully).&lt;/p&gt;
&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;p&gt;The GitHub contains more information and detailed example of usage, so go check it out and ⭐ it !&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/YJDoc2" rel="noopener noreferrer"&gt;
        YJDoc2
      &lt;/a&gt; / &lt;a href="https://github.com/YJDoc2/Bytecode" rel="noopener noreferrer"&gt;
        Bytecode
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A Rust proc-macro crate which derives functions to compile and parse back enums and structs to and from a bytecode representation
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Bytecode&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;A simple way to derive bytecode for you Enums and Structs.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What is this&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;This is a crate that provides a proc macro which will derive bytecode representation of your enums and structs, and provides compile and parse functions to convert to and from the bytecode. This also provides necessary traits to do so, in case you want to do it manually.&lt;/p&gt;

&lt;p&gt;Note : The values of the fields are compiled as little-endian values, so in the bytecode the smallest byte is at smallest location. The bytecode itself is Big-endian for certain reasons.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Example&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Cargo.toml&lt;/p&gt;

&lt;div class="highlight highlight-source-toml notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-ii"&gt;...&lt;/span&gt;
[&lt;span class="pl-en"&gt;dependencies&lt;/span&gt;]
&lt;span class="pl-ii"&gt;...&lt;/span&gt;
&lt;span class="pl-smi"&gt;bytecode&lt;/span&gt; = {&lt;span class="pl-smi"&gt;git&lt;/span&gt; = &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;https://github.com/YJDoc2/Bytecode&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt; }
&lt;span class="pl-ii"&gt;...&lt;/span&gt;
&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Code&lt;/p&gt;
&lt;div class="highlight highlight-source-rust notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;use&lt;/span&gt; bytecode&lt;span class="pl-kos"&gt;::&lt;/span&gt;&lt;span class="pl-kos"&gt;{&lt;/span&gt;&lt;span class="pl-v"&gt;Bytecodable&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-v"&gt;Bytecode&lt;/span&gt;&lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-c1"&gt;#&lt;span class="pl-kos"&gt;[&lt;/span&gt;derive&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-v"&gt;Bytecode&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-v"&gt;Debug&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-v"&gt;PartialEq&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-v"&gt;Eq&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="pl-k"&gt;pub&lt;/span&gt; &lt;span class="pl-k"&gt;enum&lt;/span&gt; &lt;span class="pl-smi"&gt;Register&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
    &lt;span class="pl-v"&gt;AX&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
    &lt;span class="pl-v"&gt;BX&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
    &lt;span class="pl-v"&gt;CX&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
    &lt;span class="pl-v"&gt;DX&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
&lt;span class="pl-kos"&gt;}&lt;/span&gt;

&lt;span class="pl-c1"&gt;#&lt;span class="pl-kos"&gt;[&lt;/span&gt;derive&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/YJDoc2/Bytecode" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>showdev</category>
      <category>computerscience</category>
      <category>programming</category>
    </item>
    <item>
      <title>How many (Human) Languages you know?</title>
      <dc:creator>YJDoc2</dc:creator>
      <pubDate>Thu, 25 Nov 2021 14:35:58 +0000</pubDate>
      <link>https://dev.to/yjdoc2/how-many-human-languages-you-know-115g</link>
      <guid>https://dev.to/yjdoc2/how-many-human-languages-you-know-115g</guid>
      <description>&lt;p&gt;Hello!&lt;/p&gt;

&lt;p&gt;Sometime ago, after coding for a bit too much time, I thought of learning a new human language as a distraction. Even though I didn't follow through on that thought, I am curious now, how many of you know multiple human languages? Which ones do you know?&lt;/p&gt;

&lt;p&gt;How did you learn them? Did you find any interesting resources, or did you take some classes or courses? Did you also, like me, try learning something as a distraction or hobby?&lt;/p&gt;

&lt;p&gt;On that note, if you do know multiple languages, do you feel that knowing multiple human languages helped you be a better developer? &lt;/p&gt;

&lt;p&gt;Please let know in comments!!!&lt;/p&gt;

&lt;p&gt;Thanks :)&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>discuss</category>
    </item>
    <item>
      <title>I Used KDE Plasma to Make Ubuntu Look (Somewhat) like MacOS</title>
      <dc:creator>YJDoc2</dc:creator>
      <pubDate>Thu, 28 Oct 2021 13:32:41 +0000</pubDate>
      <link>https://dev.to/yjdoc2/i-used-kde-plasma-to-make-ubuntu-look-somewhat-like-macos-53j9</link>
      <guid>https://dev.to/yjdoc2/i-used-kde-plasma-to-make-ubuntu-look-somewhat-like-macos-53j9</guid>
      <description>&lt;p&gt;Hello!&lt;/p&gt;

&lt;p&gt;I recently updated my Ubuntu Gnome desktop to look somewhat like MacOs. (or at least what I think looks like MacOS 😄 😄)&lt;/p&gt;

&lt;p&gt;The process was quite straightforward, and apart from a couple of minor issues, I feel it is quite good to use.&lt;/p&gt;

&lt;p&gt;Also mandatory disclaimer for Linux posts : Yes you can customize anything to look like anything, I chose this way , but you might be able to do it in some different way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Warnings before the spells (😉)
&lt;/h2&gt;

&lt;p&gt;Even though this looks great, and personally I didn't feel any problems when using it on daily basis, I did encounter some issues :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The default linking of file format to apps is not retained : for some reason the file-formats are not linked by default to certain apps, for example, by default, it tried to open .zip files with imagemagick, and a pdf with gimp, even though archive manager and document viewer were installed ?! But this is a first time issue only, you can set the default app when opening and then that will get picked next time&lt;/li&gt;
&lt;li&gt;Font size for some apps is changed : I use Alacritty+Zellij for my terminal emulator, and the default font size of it was perfect in Gnome, but in KDE plasma, by default the size is larger. This can be fixed by changing font size by &lt;code&gt;ctrl&lt;/code&gt;+ &lt;code&gt;+/-&lt;/code&gt; , but it is not retained across sessions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other than in I haven't found much issues when using KDE plasma, and in fact, personally, it feels much better than Gnome. Even it feels like it is faster than Gnome for power on to usable desktop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final results
&lt;/h2&gt;

&lt;p&gt;Finally the desktop looks like this :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7lbskski51dv8x0okys0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7lbskski51dv8x0okys0.png" alt="kde plasma desktop" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fje4b35ve5mc0jx50njy3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fje4b35ve5mc0jx50njy3.png" alt="files and terminal" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So If you want to see how to do this, read on 😄 😄&lt;/p&gt;

&lt;h2&gt;
  
  
  Install KDE Plasma
&lt;/h2&gt;

&lt;p&gt;Now to do that first, you need to install KDE Plasma desktop environment. In case you use a distribution which comes with it, like Kubuntu, you can skip this step, otherwise you'll need to install this.&lt;/p&gt;

&lt;p&gt;Now there are three packages that you can install, which will install plasma, and the main difference is the rest of the stuff they com with :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;kde-full comes with all the bells and whistles, all the plasma compatible packages and stuff. For that very reason, it is quite heavy, and has size around 1GB&lt;/li&gt;
&lt;li&gt;kde-standard is a medium sized version which comes with minimum requirements, and a few packages up top.&lt;/li&gt;
&lt;li&gt;kde-plasma-desktop contains the bare minimum of kde plasma&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I didn't want to install a full-on set up, and even the standard seemed a bit extra to me, so what I chose, was to install &lt;code&gt;kde-plasma-desktop&lt;/code&gt; and then install few more packages which I thought were necessary on top of it.&lt;/p&gt;

&lt;p&gt;To see which extra packages &lt;code&gt;kde-standard&lt;/code&gt; installs, run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# you don't need sudo for this&lt;/span&gt;
apt-cache depends kde-standard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will display a list of all dependencies of kde-standard, and you can pick-and-choose which of them you want to install on top of kde-plasma-desktop.&lt;/p&gt;

&lt;p&gt;You can check what each package is for from the official kde-plasma app website : &lt;a href="https://apps.kde.org/" rel="noopener noreferrer"&gt;https://apps.kde.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For me, I installed :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ark : an archive manager&lt;/li&gt;
&lt;li&gt;kate : simple document editor, similar to gedit&lt;/li&gt;
&lt;li&gt;kcalc : calculator&lt;/li&gt;
&lt;li&gt;muon : graphical package manager (don't look at me like that )&lt;/li&gt;
&lt;li&gt;okular : document viewer&lt;/li&gt;
&lt;li&gt;plasma-dataengines-addons, plasma-runners-addons, plasma-wallpapers-addons, plasma-widgets-addons, which are plugin/addon helpers,&lt;/li&gt;
&lt;li&gt;plasma-pa which is audio manager&lt;/li&gt;
&lt;li&gt;polkit-kde-agent-1  which is policy manager&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The total size of all this, along with &lt;code&gt;kde-plasma-desktop&lt;/code&gt; was around 200-ish MB.&lt;/p&gt;

&lt;p&gt;You can simply use &lt;code&gt;sudo apt-get install ...&lt;/code&gt; for installing all these, or use your distribution specific packge manager.&lt;/p&gt;

&lt;h3&gt;
  
  
  Note
&lt;/h3&gt;

&lt;p&gt;When installing these, at the time of kde-plasma configuration it will ask you to choose a display manager. For me the choices were &lt;code&gt;gdm3&lt;/code&gt; which is what gnome used, or &lt;code&gt;sddm&lt;/code&gt; which kde plasma uses. For plasma to work properly, you need to choose &lt;code&gt;sddm&lt;/code&gt; here. I went back to Gnome , still running sddm, and it seemed to work fine, but if needed you can revert back by using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;dpkg-reconfigure gdm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which will give you choice again, where you can choose a different display manager.&lt;br&gt;
For making KDE plasma work best, choose sddm.&lt;/p&gt;

&lt;p&gt;After installation, you should restart the system, and at the login screen, there will either be an option to choose your desktop manager, or by default it will boot in kde-plasma. For me it by defualt booted into kde-plasma.&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow a YouTube tutorial
&lt;/h2&gt;

&lt;p&gt;This is step 2. Seriously. The whole reason I decided to change my desktop environment was that I saw this, and it felt really cool.&lt;br&gt;
So follow this to the details (as much as you can) :&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=A0LiFu1eaMs" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F557xndiwrq5usc3kmbyy.jpg" alt="youtube video" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;link : &lt;a href="https://www.youtube.com/watch?v=A0LiFu1eaMs" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=A0LiFu1eaMs&lt;/a&gt;&lt;br&gt;
Also, in case you don't know this channel, this is a great channel if you're interested in Linux news and related stuff.&lt;/p&gt;

&lt;h2&gt;
  
  
  My personal changes
&lt;/h2&gt;

&lt;p&gt;The defaults in the above video are pretty good, but I needed to change few things to make it final :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The layout file comes with icons links in docks for many apps which I haven't installed, so on the dock there were many broken links, so I removed them.&lt;/li&gt;
&lt;li&gt;I needed to enable tap-to-click and natural scrolling through &lt;code&gt;system settings &amp;gt; Input devices &amp;gt; touchpad&lt;/code&gt; as I use a laptop
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcuxkeoyo028dt1qx2m5g.png" alt="Touchpad settings" width="800" height="571"&gt;
&lt;/li&gt;
&lt;li&gt;I made the top bar span end-to-end of the screen, instead of 98%&lt;/li&gt;
&lt;li&gt;In the video, the system has a dark theme by default, as he has previously installed a dark theme, but by default you will notice many system panels are still white. For that go to &lt;code&gt;system setting &amp;gt; Appearence &amp;gt; Get new Global theme&lt;/code&gt;, and install &lt;code&gt;Layan look and feel theme&lt;/code&gt;. Choose the dark theme, and this will apply dark theme globally. 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F29qdzgfv4xgx547y99fu.png" alt="Global Theme Settings" width="800" height="571"&gt;
&lt;/li&gt;
&lt;li&gt;I couldn't find the &lt;code&gt;thumbnail&lt;/code&gt; task switcher, so I installed &lt;code&gt;MediumDefault&lt;/code&gt; in &lt;code&gt;System Settings &amp;gt; Window Management &amp;gt; Task Switcher&lt;/code&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnwffgjuhgwdqipw5xyss.png" alt="Task switcher settings" width="800" height="571"&gt;
&lt;/li&gt;
&lt;li&gt;I also disabled desktop icons through &lt;code&gt;right click on desktop &amp;gt; configure desktop and wallpaper &amp;gt;  wallpaper &amp;gt; layout&lt;/code&gt; and choose desktop instead of folder view
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjkfpd1ns3lasybqumtz6.png" alt="Remove desktop icons" width="728" height="574"&gt;
&lt;/li&gt;
&lt;li&gt;I also reverted the window buttons to the right side, and kept the maximize button, as that felt better to me&lt;/li&gt;
&lt;li&gt;I also added an extra application launcher widget in the dock&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's how I got the system I am using now. It looks cool, and feels nice to use 😄 😄 😄&lt;/p&gt;

&lt;p&gt;In case you decide to change your desktop as per this, let me know how kde-plasma feels to you in comments. If you already have a setup that looks and feels cool, please post its pictures in the comments too, I would really like to see them :)&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;p&gt;Notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to install kde plasma : &lt;a href="https://itsfoss.com/install-kde-on-ubuntu/" rel="noopener noreferrer"&gt;https://itsfoss.com/install-kde-on-ubuntu/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;find reverse dependencies : &lt;a href="https://askubuntu.com/questions/135267/whats-the-difference-between-kde-packages" rel="noopener noreferrer"&gt;https://askubuntu.com/questions/135267/whats-the-difference-between-kde-packages&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Remove desktop icons : &lt;a href="https://www.reddit.com/r/kde/comments/6vfvxj/how_do_i_turn_off_folder_view_desktop_on_plasma/" rel="noopener noreferrer"&gt;https://www.reddit.com/r/kde/comments/6vfvxj/how_do_i_turn_off_folder_view_desktop_on_plasma/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>linux</category>
      <category>productivity</category>
      <category>tutorial</category>
      <category>showdev</category>
    </item>
    <item>
      <title>How to squash commits in a PR</title>
      <dc:creator>YJDoc2</dc:creator>
      <pubDate>Fri, 27 Aug 2021 11:01:10 +0000</pubDate>
      <link>https://dev.to/dj-unicode/how-to-squash-commits-in-a-pr-e8i</link>
      <guid>https://dev.to/dj-unicode/how-to-squash-commits-in-a-pr-e8i</guid>
      <description>&lt;p&gt;Helped by &lt;a href="https://github.com/palkadhirawani" rel="noopener noreferrer"&gt;Palka&lt;/a&gt; , &lt;a href="https://github.com/dedsec29" rel="noopener noreferrer"&gt;Parth&lt;/a&gt;, and &lt;a href="https://github.com/YatharthVyas" rel="noopener noreferrer"&gt;Yatharth&lt;/a&gt;.&lt;br&gt;
Header image created by &lt;a href="https://github.com/saloni3121" rel="noopener noreferrer"&gt;Saloni&lt;/a&gt;. Git illustration in text created by &lt;a href="https://github.com/panchalmilan" rel="noopener noreferrer"&gt;Milan&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Hello everyone !&lt;br&gt;
As you might be aware, hacktoberfest is approaching, and in about a month many of you will be helping out on open source projects. Of course, working on projects is a side effect, you know why we really do it...😏😏 To plant a tree, obviously 🌳🌲🌳🌲 (Seriously, we should do that seeing the amount of wildfires this year)&lt;/p&gt;

&lt;p&gt;Anyway, while making PRs, you might be asked to squash formatting or spelling error commits, and to save you a Google search, I am writing this post to show you why, when and how to squash commits in your PR.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why would you ever want to squash something???
&lt;/h2&gt;

&lt;p&gt;So imagine this, you have written your beautiful code, written comments in a well known format, the code is compiling and working, and you satisfyingly make a commit with the perfect commit message.... Only to realize later that you have made a spelling error 🥲🤦 Now you can use a soft reset, fix the error, and re-commit, leaving no one any wiser, but what if you had already pushed the commit in PR?&lt;/p&gt;

&lt;p&gt;More realistically, imagine you're working on a PR, and as you're pushing the commits, and they're getting reviewed you accidentally mess up formatting and commit. Or along an ongoing discussion in a PR, you have made some patch commits and now before merging the PR you want to combine them, as old patches don't really make sense . This is where squashing the commits would come handy.&lt;/p&gt;

&lt;p&gt;Squashing allows to combine or 'squash' the commits together, leaving a nice git history behind. That way you can combine all your patch commits into a single commit, or squash formatting and spelling error commits into other commits, leaving behind a git history of only necessary commits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0on6d33b4pk9zuylmzg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0on6d33b4pk9zuylmzg.jpeg" alt="Git squash example" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  When should the squashing be done?
&lt;/h2&gt;

&lt;p&gt;Now on an important note, you should not squash commits if they're pushed to the main branch of the repository. Squashing changes git history, which means that history of all forks of that branch will be inconsistent with your repository, giving everyone a lot of merge conflicts, and you know how &lt;em&gt;you&lt;/em&gt; were when you got conflicts, right 😉 😉&lt;/p&gt;

&lt;p&gt;However if you're working on a branch which is not main for an issue, and you intend to make a PR to the main branch, it is totally fine to squash the commits. As most of the times you alone are working on that specific branch, even if the history changes it will not affect anyone else. Then once everything is done, you can merge the PR without any history conflicts.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to squash commits
&lt;/h2&gt;

&lt;p&gt;Let us see with an example. Consider a project on which you're working, that already has some commits on its main branch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# run git log --pretty=oneline&lt;/span&gt;
7dc92d4...&lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; Main&lt;span class="o"&gt;)&lt;/span&gt; Add ReadMe
d3395b0... Initial Commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now to grow some trees 🌲🌳 you decide to work on this project and help in solving issue-1. So you fork and clone the project, make a branch named issue-1 like a good contributor and start working on the issue.&lt;/p&gt;

&lt;p&gt;You add feature 1 and feature 2 in their own commits and make a PR. After discussing with the reviewers, you find that there was a bug in your commits and you make a commit to fix it.&lt;/p&gt;

&lt;p&gt;Now, your git history looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# git log --pretty=oneline&lt;/span&gt;
b2f4c83... &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; issue-1&lt;span class="o"&gt;)&lt;/span&gt; Bug Fix
32e414f... Add Feature 2
7654633... Add Feature 1
7dc92d4... &lt;span class="o"&gt;(&lt;/span&gt;Main&lt;span class="o"&gt;)&lt;/span&gt; Add ReadMe
d3395b0... Initial Commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You have your main branch's head on &lt;code&gt;Add Readme&lt;/code&gt; commit, and issue-1's head on &lt;code&gt;Bug Fix&lt;/code&gt; commit. &lt;/p&gt;

&lt;p&gt;Now as you're about to start with feature 3 , when someone comments on your PR, noticing a formatting and spelling error😭😢&lt;br&gt;
Ah well.... You fix those, make a commit and start working on the feature 3. After finally making if work, your commit history now looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# git log --pretty=oneline&lt;/span&gt;
f592171... &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; issue-1&lt;span class="o"&gt;)&lt;/span&gt; Add Feature 3
574b345... Fix Formatting
b2f4c83... Bug Fix
32e414f... Add Feature 2
7654633... Add Feature 1
7dc92d4... &lt;span class="o"&gt;(&lt;/span&gt;Main&lt;span class="o"&gt;)&lt;/span&gt; Add ReadMe
d3395b0... Initial Commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you push these to your repository, and wait eagerly to get it merged, someone asks you to squash the formatting commit, so the main repository history would look nice.&lt;/p&gt;

&lt;p&gt;Now to squash the commits, you need to run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git rebase &lt;span class="nt"&gt;-i&lt;/span&gt; HEAD~4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-i&lt;/code&gt; option make the rebase interactive, and &lt;code&gt;HEAD~4&lt;/code&gt; considers last 4 commits from current Head position for the rebase. If your formatting commit was 5 commits before current, you would replace 4 with 6 or some numbers greater than 5, to get all commits till there.&lt;/p&gt;

&lt;p&gt;After running this, you will see a message like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pick 32e414f Add Feature 2
pick b2f4c83 Bug Fix
pick 574b345 Fix Formatting
pick f592171 Add Feature 3

&lt;span class="c"&gt;# Rebase 7654633..f592171 onto f592171 (4 commands)&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# Commands:&lt;/span&gt;
&lt;span class="c"&gt;# p, pick &amp;lt;commit&amp;gt; = use commit&lt;/span&gt;
&lt;span class="c"&gt;# r, reword &amp;lt;commit&amp;gt; = use commit, but edit the commit message&lt;/span&gt;
&lt;span class="c"&gt;# e, edit &amp;lt;commit&amp;gt; = use commit, but stop for amending&lt;/span&gt;
&lt;span class="c"&gt;# s, squash &amp;lt;commit&amp;gt; = use commit, but meld into previous commit&lt;/span&gt;
&lt;span class="c"&gt;# f, fixup &amp;lt;commit&amp;gt; = like "squash", but discard this commit's log message&lt;/span&gt;
&lt;span class="c"&gt;# x, exec &amp;lt;command&amp;gt; = run command (the rest of the line) using shell&lt;/span&gt;
&lt;span class="c"&gt;# b, break = stop here (continue rebase later with 'git rebase --continue')&lt;/span&gt;
&lt;span class="c"&gt;# d, drop &amp;lt;commit&amp;gt; = remove commit&lt;/span&gt;
&lt;span class="c"&gt;# l, label &amp;lt;label&amp;gt; = label current HEAD with a name&lt;/span&gt;
&lt;span class="c"&gt;# t, reset &amp;lt;label&amp;gt; = reset HEAD to a label&lt;/span&gt;
&lt;span class="c"&gt;# m, merge [-C &amp;lt;commit&amp;gt; | -c &amp;lt;commit&amp;gt;] &amp;lt;label&amp;gt; [# &amp;lt;oneline&amp;gt;]&lt;/span&gt;
&lt;span class="c"&gt;# .       create a merge commit using the original merge commit's&lt;/span&gt;
&lt;span class="c"&gt;# .       message (or the oneline, if no original merge commit was&lt;/span&gt;
&lt;span class="c"&gt;# .       specified). Use -c &amp;lt;commit&amp;gt; to reword the commit message.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# These lines can be re-ordered; they are executed from top to bottom.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# If you remove a line here THAT COMMIT WILL BE LOST.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# However, if you remove everything, the rebase will be aborted.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# Note that empty commits are commented out&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shows first, the commits : from oldest to latest, and then available options, such as squash, edit, fixup... Git can be really powerful once you get to know it... But I don't know much of it other than handful of commands, so let us get on with squashing the formatting commit.&lt;/p&gt;

&lt;p&gt;To perform an action on a commit, you change the word 'pick' before that commit to that action, as described in comments. To squash the formatting commit, you change it as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pick 32e414f Add Feature 2
pick b2f4c83 Bug Fix
squash 574b345 Fix Formatting
pick f592171 Add Feature 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After saving this you will get another commit message, showing commit message before the squashed commit, and the squash commit message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# This is a combination of 2 commits.&lt;/span&gt;
&lt;span class="c"&gt;# This is the 1st commit message:&lt;/span&gt;

Bug Fix

&lt;span class="c"&gt;# This is the commit message #2:&lt;/span&gt;

Fix Formatting

&lt;span class="c"&gt;# Please enter the commit message for your changes. Lines starting&lt;/span&gt;
&lt;span class="c"&gt;# with '#' will be ignored, and an empty message aborts the commit.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# Date:      Thu Aug 19 19:03:51 2021 +0530&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# interactive rebase in progress; onto 7654633&lt;/span&gt;
&lt;span class="c"&gt;# Last commands done (3 commands done):&lt;/span&gt;
&lt;span class="c"&gt;#    pick b2f4c83 Bug Fix&lt;/span&gt;
&lt;span class="c"&gt;#    squash 574b345 Fix Formatting&lt;/span&gt;
&lt;span class="c"&gt;# Next command to do (1 remaining command):&lt;/span&gt;
&lt;span class="c"&gt;#    pick f592171 Add Feature 3&lt;/span&gt;
&lt;span class="c"&gt;# You are currently rebasing branch 'issue-1' on '7654633'.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# Changes to be committed:&lt;/span&gt;
&lt;span class="c"&gt;#       modified:   readme.md&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In case the commit was something like a patch in series where you want to keep the message, this will allow you to do that. Otherwise if you just want to forego the message, you can also use the &lt;code&gt;fixup&lt;/code&gt; instead of &lt;code&gt;squash&lt;/code&gt;. Here you can comment the second commit message, and save, like usual git commit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# This is a combination of 2 commits.&lt;/span&gt;
&lt;span class="c"&gt;# This is the 1st commit message:&lt;/span&gt;

Bug Fix

&lt;span class="c"&gt;# This is the commit message #2:&lt;/span&gt;

&lt;span class="c"&gt;# Fix Formatting&lt;/span&gt;

&lt;span class="c"&gt;# Please enter the commit message for your changes. Lines starting&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# git log --pretty=oneline&lt;/span&gt;
29768cb... &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; issue-1&lt;span class="o"&gt;)&lt;/span&gt; Add Feature 3
10c38d8... Bug Fix
32e414f... Add Feature 2
7654633... Add Feature 1
7dc92d4... &lt;span class="o"&gt;(&lt;/span&gt;Main&lt;span class="o"&gt;)&lt;/span&gt; Add ReadMe
d3395b0... Initial Commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ah, now you have a clean git history, alas, if you try to push this to your repository branch, you will get error saying cannot push because histories are different. Your repository has the formatting commit whereas your local has no such thing in its history. To fix this you'll have to force push :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push &lt;span class="nt"&gt;-f&lt;/span&gt; origin issue-1:issue-1
&lt;span class="c"&gt;# as you're on issue-1 branch, you can leave the last part, but I like the extra confirmation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this your PR will be updated, hopefully merged, and you'll be one step closer to planting that plant 🌱&lt;/p&gt;




&lt;p&gt;Hope you found this useful, and may your PRs be clean :)&lt;/p&gt;

&lt;p&gt;Since I started this post talking about hacktoberfest, let me end with the same. Do you have any repository that you plan to open up for contributing to this hacktoberfest? Sometimes it is hard to make your repository visible in all repos open for contributing, so this is kind of an early call... If you have any interesting repo you would like to open for contribution, post them in the comments. Let's start planting the trees. 🌱🌱🌱&lt;/p&gt;

</description>
      <category>git</category>
      <category>opensource</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Completely Oxidizing My Terminal Setup</title>
      <dc:creator>YJDoc2</dc:creator>
      <pubDate>Thu, 22 Jul 2021 10:44:00 +0000</pubDate>
      <link>https://dev.to/yjdoc2/completely-oxidizing-my-terminal-setup-43d8</link>
      <guid>https://dev.to/yjdoc2/completely-oxidizing-my-terminal-setup-43d8</guid>
      <description>&lt;p&gt;Hello!&lt;br&gt;
I recently oxidized my terminal setup, by converting all of my terminal programs to rust based programs. There were some hiccups in making it all work together, but in the end, my new setup is :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/alacritty/alacritty" rel="noopener noreferrer"&gt;Alacritty&lt;/a&gt; as my terminal emulator&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://starship.rs/" rel="noopener noreferrer"&gt;Starship&lt;/a&gt; as my shell prompt&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.nushell.sh/" rel="noopener noreferrer"&gt;nushell&lt;/a&gt; as my shell&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.nushell.sh/" rel="noopener noreferrer"&gt;zellij&lt;/a&gt; as my terminal multiplexer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note : nushell and zellij both are still in their beta versions, and have few &lt;a href="https://github.com/zellij-org/zellij/issues/615" rel="noopener noreferrer"&gt;known issues&lt;/a&gt;, so if you want an absolutely reliable env, use bash/fish/zsh for shell and screen/tmux for terminal multiplexer.&lt;/p&gt;
&lt;h2&gt;
  
  
  Original setup
&lt;/h2&gt;

&lt;p&gt;Before changing this, I had already installed Alacritty and starship and had used it for few days before switching back to default gnome terminal emulator with starship. The main reason I switched back was that a lot of times I ran multiple processes in parallel, such as running react frontend and node backend. I was used to doing this using the tabs of gnome emulator, and as Alacritty has clearly specified in its Readme, it has no intention of adding a terminal multiplexer, and users would need to use an external one such as tmux to do that (Which makes sense).&lt;/p&gt;

&lt;p&gt;Unfortunately, I didn't want to install and setup another program to make it work, and I needed the functionality of multiplexed terminals in single window, rather than opening a new window each time ; which is why I moved back to gnome terminal emulator. In this, I kept starship, as I really liked it, and it was quite useful.&lt;/p&gt;
&lt;h2&gt;
  
  
  A second look
&lt;/h2&gt;

&lt;p&gt;I had checked out nushell about a year ago, and it seemed very interesting, but then I felt it was a little too complex, and I felt like I wouldn't need all the features it provides, so I didn't try using it.&lt;/p&gt;

&lt;p&gt;Few days back, I came across &lt;a href="https://www.poor.dev/blog/performance/" rel="noopener noreferrer"&gt;this&lt;/a&gt; retweeted by official Rust twitter account, which explained how zellij, a rust terminal workspace solved some of the performance issues. (It is really well writter, do check it out!)&lt;/p&gt;

&lt;p&gt;While checking out zellij, I remembered nushell, and went back to its site to check that out as well. This time it didn't felt as complex, as well as its features looked awesome (you can "preview" an image in the terminal itself 😲 😲 ).&lt;/p&gt;

&lt;p&gt;With this, I decided to convert all my terminal setup to Rust.&lt;/p&gt;
&lt;h2&gt;
  
  
  Upgrading
&lt;/h2&gt;

&lt;p&gt;I had already installed alacritty as per their &lt;a href="https://github.com/alacritty/alacritty/blob/master/INSTALL.md" rel="noopener noreferrer"&gt;installation guide&lt;/a&gt;, as well as had starship set up. Now I had to install and setup nushell and zellij.&lt;/p&gt;

&lt;p&gt;Installation process was quite straightforward, using cargo, and for nushell I had to install some other libraries for extra features using apt-get, but it went smoothly following the instructions on their pages :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.nushell.sh/book/installation.html" rel="noopener noreferrer"&gt;nushell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zellij.dev/documentation/installation.html" rel="noopener noreferrer"&gt;zellij&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After the installation, it was time to set it all up together, where I hit a couple of issues. First, I wanted to integrate zellij with alacritty and nushell, so that it can manage multiple sessions.&lt;/p&gt;

&lt;p&gt;Initially I though setting the startup command in nushell to zellij would work, as startup command are run at start of each shell session. But quickly I found out I was wrong, as after starting nushell, it would first run zellij, which would keep running with default bash shell, and thus nushell would not actually run until I quit zellij.&lt;/p&gt;

&lt;p&gt;Then I found out that zellij can be launched with specific shell as an argument, and alacritty has an option to choose which shell to run in its configuration, which was great because I didn't want to change system default shell to nu (its still in beta).&lt;/p&gt;

&lt;p&gt;So first, I copied default &lt;code&gt;alacritty.yml&lt;/code&gt; to my home directory. The default file comes when installing from source, or else can be copied from their github repository. It has an option somewhere in the middle for shell :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Shell&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# You can set `shell.program` to the path of your favorite shell, e.g.&lt;/span&gt;
&lt;span class="c1"&gt;# `/bin/fish`. Entries in `shell.args` are passed unmodified as arguments to the&lt;/span&gt;
&lt;span class="c1"&gt;# shell.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Default:&lt;/span&gt;
&lt;span class="c1"&gt;#   - (macOS) /bin/bash --login&lt;/span&gt;
&lt;span class="c1"&gt;#   - (Linux/BSD) user login shell&lt;/span&gt;
&lt;span class="c1"&gt;#   - (Windows) powershell&lt;/span&gt;
&lt;span class="c1"&gt;#shell:&lt;/span&gt;
&lt;span class="c1"&gt;#  program: /bin/bash&lt;/span&gt;
&lt;span class="c1"&gt;#  args:&lt;/span&gt;
&lt;span class="c1"&gt;#    - --login&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is commented by default. I thought uncommenting and changing it to zellij , and passing the option to set shell to nushell would work, so I set it to :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;program&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;~/.cargo/bin/zellij&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;options --default-shell nu&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which ... didn't work. Whenever I would launch alacritty, and it would immediately close, with no error message. I tried opening it from commandline of gnome shell, but it didn't leave any error message there, and that lead me to go through its github issues, and find how to make it generate debug dump, which I though would be helpful to find what is the issue, ... but it didn't work either 😅 😄&lt;/p&gt;

&lt;p&gt;After that I figured that it might be possible that it might be because I was giving all the arguments to it in a single arg. Usually when we give args, program gets them as array of strings, and then it can parse it, and [I think] shell splits it by space to form the array. But in this, all was in a single arg entry, and thus was getting sent to program (zellij) as single argument, instead of 'options' , '--default-shell' and 'nu' being separate args.&lt;/p&gt;

&lt;p&gt;After figuring this out, I separated them as individual args, and finally my config looks as :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;program&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;~/.cargo/bin/zellij&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;options&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;--default-shell&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;nu&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and viola! It worked. Now I had to only set starship as shell prompt which was easy, as nushell has that as an &lt;a href="https://www.nushell.sh/book/configuration.html#prompt-configuration" rel="noopener noreferrer"&gt;example&lt;/a&gt;. And my terminal setup was ready and oxidized. 🎉 🎉 🎉&lt;/p&gt;

&lt;p&gt;Now it looks like :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fanna7hf79utr21eom0w7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fanna7hf79utr21eom0w7.png" alt="screenshot of my terminal" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fojek6l1fk9sonunm4bpc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fojek6l1fk9sonunm4bpc.png" alt="use example" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, did you find this interesting or helpful? &lt;br&gt;
Did you already used any of these , or thinking of trying them out?&lt;br&gt;
Let me know in the comments!&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>shell</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to create a new react npm package?</title>
      <dc:creator>YJDoc2</dc:creator>
      <pubDate>Mon, 12 Jul 2021 11:25:58 +0000</pubDate>
      <link>https://dev.to/yjdoc2/how-to-create-a-new-react-npm-package-45g5</link>
      <guid>https://dev.to/yjdoc2/how-to-create-a-new-react-npm-package-45g5</guid>
      <description>&lt;p&gt;Hello, I want to create a new component package for react, which I might publish on npm later. I haven't done this before,so can you tell me the steps needed to setup a basic template for a new package, something like what create-react-app does, but for packages. Also most packages on npm have typscript types along with them, so would that require some extra setup steps? Please comment if you have any idea.&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>help</category>
      <category>react</category>
      <category>webdev</category>
      <category>npm</category>
    </item>
    <item>
      <title>Computer Networks, Made interactive</title>
      <dc:creator>YJDoc2</dc:creator>
      <pubDate>Thu, 01 Jul 2021 07:41:17 +0000</pubDate>
      <link>https://dev.to/yjdoc2/computer-networks-made-interactive-37ge</link>
      <guid>https://dev.to/yjdoc2/computer-networks-made-interactive-37ge</guid>
      <description>&lt;p&gt;Hey!&lt;br&gt;
&lt;em&gt;The short version is :&lt;/em&gt; We made a network simulator, where you can setup a network structure, decide packet processing function for each node which is in JS, as well as their memory which is a JS object, and then see in animation how with given packets routing and processing will be done. It is live at &lt;a href="https://yjdoc2.github.io/Network-Simulator/" rel="noopener noreferrer"&gt;https://yjdoc2.github.io/Network-Simulator/&lt;/a&gt;, and as you can save and load them in json format, we have already made couple of examples to see, which are at &lt;a href="https://github.com/YJDoc2/Network-Simulator/" rel="noopener noreferrer"&gt;https://github.com/YJDoc2/Network-Simulator/&lt;/a&gt; in examples directory. Please give it a star if you found this interesting, and let me know your thoughts on this in the comments.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Off we go to the longer version!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is this?
&lt;/h2&gt;

&lt;p&gt;This is a simple network simulator, which has one task : to run the processing function for each packet in queue of each node, then animate the packet forwarding according to the packets returned by the function. Other than the format of return value of the function, there is no restrictions : you can use any valid JS function as the node function to process packets, and each node has a memory, which you ca interact with, and it is a JS object. These simulations can be stored in local storage and loaded from there, or exported and loaded from a JSON file. You can run the simulation step by step, checking memory and queues at each step, or just let the animation play out.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Goal
&lt;/h2&gt;

&lt;p&gt;When we started this, we had a simple reason behind this : when we were learning computer networks, it had many concepts such as routers, link layer, data layer etc. When learning we would learn why these things were, and how they were supposed to work, but there was no way we could actually interact with these : There is no way we could easily do router programming to implement routing algorithms, unless someone was ready to invest in a router, along with setting up the network and letting students play with it, and we could not actually see how link layer or data layer interacts with packet unless we could go deep in kernel and networking stack programming.&lt;/p&gt;

&lt;p&gt;We wanted to make something were people can do all of these, with relative ease. Then I came across &lt;a href="https://www.youtube.com/watch?v=shn38x7BbO0" rel="noopener noreferrer"&gt;this&lt;/a&gt; video from computerphile, which described building a virtual switching network in a computer using VMs. But this was still complex to setup, and required installation of things. But using the virtual network as starting point, we developed the idea of network emulator.&lt;/p&gt;

&lt;p&gt;As we thought more and more, on this we figured this could be more than just a simple website for simulating networks. This could be used as a learning tool by students and teachers, where teachers can create simulations, export them as JSON, and students could run them, learn from them, and modify them.&lt;/p&gt;

&lt;p&gt;This could allow students to not only see the existing algorithms in action as the packets are animated moving from one node to another, and can be color marked to trace them through nodes ; but also allow them to modify them or develop new algorithms which can be tested easily. This not only can be useful for network, but also for cybersecurity demos : to show Man in Middle attacks, to show how diffie hellman allows securely generating private keys using potentially compromised channels.&lt;/p&gt;

&lt;p&gt;Now we can see this in action, get our hands in it and change things to see how it would affect the simulation, and not rely on just imagination to see it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;That's so much of text ! Lets see some GIF demos :&lt;/p&gt;

&lt;h3&gt;
  
  
  ARP spoofing
&lt;/h3&gt;

&lt;p&gt;Where node A tried to get address of node B, but Man In Middle (MIM) gives it its own address to read the requests.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsjc7912wkz5l384rowwi.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsjc7912wkz5l384rowwi.gif" alt="ARP Spoofing DEMO GIF" width="690" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Firewall
&lt;/h3&gt;

&lt;p&gt;The firewall blocks requests from blocked IP of node A, but allows node B packets to pass through.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1lqq4pw163ekqmzgqptw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1lqq4pw163ekqmzgqptw.gif" alt="FireWall Demo GIF" width="690" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have these both example's JSON file at our git repo, and are trying to add more examples like diffie hellman&lt;/p&gt;

&lt;h2&gt;
  
  
  Back to the project
&lt;/h2&gt;

&lt;p&gt;So, then we made the website! It is a frontend-only website, so once loaded, it does not need any network connection. It uses Svelte for frontend, which makes it quite light compared to React, as svelte is a compiler :)&lt;/p&gt;

&lt;p&gt;This can save projects in local storage, and load saved projects from there, export them in JSON format. It can give custom colors to enqueued packets, so you can trace that packet, and packets generated due to it. It has a logging functionality, which can allow you to log things.&lt;/p&gt;

&lt;p&gt;We are working on improving its usability, as in the starting it can be a bit complicated to navigate, So if you re interested in this, an would like to read a post explaining how to use this, please leave a comment 😄 😄&lt;/p&gt;

&lt;p&gt;This is hosted using github pages at &lt;a href="https://yjdoc2.github.io/Network-Simulator/" rel="noopener noreferrer"&gt;https://yjdoc2.github.io/Network-Simulator/&lt;/a&gt;, and its repo is at &lt;a href="https://github.com/YJDoc2/Network-Simulator" rel="noopener noreferrer"&gt;https://github.com/YJDoc2/Network-Simulator&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also we entered this in the hashnode HarperDB hackethon, so be sure to check that post out too : &lt;a href="https://vatsal13.hashnode.dev/network-simulator-in-svelte" rel="noopener noreferrer"&gt;https://vatsal13.hashnode.dev/network-simulator-in-svelte&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  And Finally
&lt;/h2&gt;

&lt;p&gt;This was out first project using svelte, also first time using Vis JS and SVG JS. We faced some problems combining them, but it was interesting ;) But this post is long as it is ; so, if you would like to know our experience about working with them, please leave a comment telling what would you like to know, and I'll make a post about it. 😉&lt;/p&gt;

&lt;p&gt;Please go and checkout the project, make sure to star it on github, and leave a comment here to let us know what you think about the project 😄&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>svelte</category>
      <category>computerscience</category>
    </item>
  </channel>
</rss>
