<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/rss.xsl" type="text/xsl"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>furtidev</title>
      <link>https://furtidev.github.io</link>
      <description>Personal blog of furti discussing software, manga and games.</description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://furtidev.github.io/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Sun, 31 Aug 2025 00:00:00 +0000</lastBuildDate>
      
      <item>
          <title>Please, let my laptop sleep</title>
          <pubDate>Sun, 31 Aug 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://furtidev.github.io/blog/let-my-laptop-sleep/</link>
          <guid>https://furtidev.github.io/blog/let-my-laptop-sleep/</guid>
          <description xml:base="https://furtidev.github.io/blog/let-my-laptop-sleep/">&lt;p&gt;&lt;code&gt;suspend&#x2F;sleep&lt;&#x2F;code&gt; on Linux has been a hit or miss for me. Sometimes it&#x27;d work fine, other times it won&#x27;t. By &quot;won&#x27;t&quot; I mean a very specific sequence:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Power is cut off from the keyboard, mouse and screen&lt;&#x2F;li&gt;
&lt;li&gt;I can tell my laptop is still on, since the indicator light is still lit&lt;&#x2F;li&gt;
&lt;li&gt;Either I wait for the battery to drain or I hard-poweroff the laptop&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Guess what I used to do? I&#x27;m surprised no components are damaged yet. But perhaps that&#x27;s because components that could be damaged were already not receiving power. It&#x27;s messy. But why is it happening? Had no clue for a long time. I sought answers from many, yet found none. But I recall one of them told me some systems have trouble with this. This was actually a good hint, but although useless to then-me. The ArchWiki entry on power management also had a good hint:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Suspend to RAM (aka suspend)&lt;&#x2F;strong&gt; &lt;br&gt;
The S3 sleeping state as &lt;mark&gt;defined by ACPI&lt;&#x2F;mark&gt;, ...&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;So it&#x27;s some sort of discrepancy between the ACPI tables in my firmware and the Linux kernel. If only I had investigated that earlier, I could have spared myself from a ton of pain.&lt;&#x2F;p&gt;
&lt;p&gt;On some laptops, the &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;wiki.archlinux.org&#x2F;title&#x2F;DSDT&quot;&gt;DSDT&lt;&#x2F;a&gt; table is tuned specifically for Windows in mind, and so it&#x27;s difficult for the Linux kernel to interface with it properly. Most functionalities &lt;em&gt;seemed&lt;&#x2F;em&gt; to work, but sleep and shutdown consistently gave me trouble.&lt;&#x2F;p&gt;
&lt;p&gt;Apparently you can re-build the firmware DSDT table, but doesn&#x27;t seem fool-proof and rather unnecessary in my case. Instead, I ended up adding a few kernel parameters to my GRUB config to camouflage the Linux kernel as Windows when interfacing with ACPI:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&#x2F;etc&#x2F;default&#x2F;grub&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #737C73;&quot;&gt;# GRUB boot loader configuration&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;GRUB_DEFAULT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;&amp;#39;0&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;GRUB_TIMEOUT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;&amp;#39;5&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;GRUB_DISTRIBUTOR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;&amp;#39;EndeavourOS&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;GRUB_CMDLINE_LINUX_DEFAULT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;&amp;#39;nowatchdog nvme_load=YES loglevel=3 acpi_osi=! acpi_osi=&amp;quot;Windows 2020&amp;quot;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #737C73;&quot;&gt; # only use Windows 2020 as the interface&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;GRUB_CMDLINE_LINUX&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The kernel parameters and their possible values are all documented in the DSDT article I linked above. Ironically, I found this solution using ChatGPT. It&#x27;s a bit sad. It&#x27;s all well documented on ArchWiki, and I opted for slop instead. I was actually surprised.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Wow, AI fixed a problem nobody else could?1?! It&#x27;s joever.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;But turns out it&#x27;s a very common problem, just that the people I asked also never read the ArchWiki article on power management. But ChatGPT? Oh, it scraped the entire internet alright. So what&#x27;s the takeaway from all this? It&#x27;s to always READ THE FUCKING MANUAL.&lt;&#x2F;p&gt;
&lt;p&gt;Apparently there are plenty of other reasons why power management could go wrong on Linux, some of them are more complicated than others. I found a good article on ACPI and Linux: &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;enaix.github.io&#x2F;2025&#x2F;06&#x2F;03&#x2F;acpi-conspiracy.html&quot;&gt;How I discovered that Bill Gates monopolized ACPI in order to break Linux&lt;&#x2F;a&gt;. You SHOULD read it. NOW. I&#x27;m glad mine was very simple to fix. Finally, I can put my laptop to sleep as I sing it a sweet lullaby on Rust and the borrow checker.&lt;&#x2F;p&gt;
</description>
      </item>
      
      
      
      <item>
          <title>Setting up Wine + Bottles on an external drive</title>
          <pubDate>Sun, 25 May 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://furtidev.github.io/blog/gaming-on-linux/</link>
          <guid>https://furtidev.github.io/blog/gaming-on-linux/</guid>
          <description xml:base="https://furtidev.github.io/blog/gaming-on-linux/">&lt;h2 id=&quot;toc&quot;&gt;ToC&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;furtidev.github.io&#x2F;blog&#x2F;gaming-on-linux&#x2F;#step-1-setup-flatpak&quot;&gt;Step 1: Setup Flatpak&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;furtidev.github.io&#x2F;blog&#x2F;gaming-on-linux&#x2F;#step-2-setup-bottles&quot;&gt;Step 2: Setup Bottles&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;furtidev.github.io&#x2F;blog&#x2F;gaming-on-linux&#x2F;#step-3-running-games&quot;&gt;Step 3: Running games&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So here&#x27;s the deal:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I&#x27;m dual booting with Windows 10.&lt;&#x2F;li&gt;
&lt;li&gt;My Linux partition doesn&#x27;t have as much storage, because at the time, I thought I wouldn&#x27;t want to play games while on the Linux boot and nothing else takes much space. Movies? Manga? Anime? I can store them on one of the Windows partitions easily (thanks to whoever wrote NTFS drivers for Linux).&lt;&#x2F;li&gt;
&lt;li&gt;I don&#x27;t want to boot into Windows 10 everytime I want to play a game.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It&#x27;s simple enough to run native Linux games while storing them on an NTFS partition. But, what if I want to play games that don&#x27;t have Linux builds (or have broken Linux builds)? I&#x27;ll need Wine. I&#x27;m familiar with &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;usebottles.com&quot;&gt;Bottles&lt;&#x2F;a&gt;, a very easy to use Wine prefix manager.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s a bit involved to set up Bottles in this scenario to use Windows partitions (could be external drives, but I only have one drive split into partitions, takes the same process) for storage instead of filling up my already tiny Linux one. But it isn&#x27;t that hard and I want to document it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-1-setup-flatpak&quot;&gt;Step 1: Setup Flatpak&lt;&#x2F;h3&gt;
&lt;p&gt;You need Flatpak if you want to use Bottles since it&#x27;s mainly distributed through Flathub. I know, it&#x27;s a bit annoying and flatpaks are space hungry (because of which this whole blog exists) but it is what it is.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;flatpak.org&#x2F;setup&#x2F;&quot;&gt;Install Flatpak&lt;&#x2F;a&gt; through your distro&#x27;s intended way, and setup Flathub on it. Don&#x27;t install anything with it yet.&lt;&#x2F;p&gt;
&lt;p&gt;We want to change some configuration. Mount your desired drive where you want to store all this. For me, it&#x27;s a Windows partition mounted at &lt;code&gt;&#x2F;run&#x2F;media&#x2F;furtidev&#x2F;Games&lt;&#x2F;code&gt;. This drive always needs to be mounted before you run Bottles after we&#x27;re done.&lt;&#x2F;p&gt;
&lt;p&gt;First things first, create the configuration directory if it doesn&#x27;t exist already:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #737C73;&quot;&gt;# -p doesn&amp;#39;t error out if a directory already exist.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt; sudo mkdir -p &#x2F;etc&#x2F;flatpak&#x2F;installations.d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next up, let&#x27;s edit a file there:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt; sudoedit &#x2F;etc&#x2F;flatpak&#x2F;installations.d&#x2F;gaming.conf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #737C73;&quot;&gt; # could be named anything&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Append this:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&#x2F;etc&#x2F;flatpak&#x2F;installations.d&#x2F;gaming.conf&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[Installation &amp;quot;gaming&amp;quot;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Path=&#x2F;run&#x2F;media&#x2F;path&#x2F;to&#x2F;your&#x2F;drive&#x2F;flatpak # for me: &#x2F;run&#x2F;media&#x2F;furtidev&#x2F;Games&#x2F;Linux&#x2F;Flatpak&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;DisplayName=Flatpak installation for gaming needs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;StorageType=harddisk # mmc, sdcard, harddisk, network&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You need to ensure that &lt;code&gt;Path&lt;&#x2F;code&gt; already exists. Save and you&#x27;re done.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-2-setup-bottles&quot;&gt;Step 2: Setup Bottles&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt; flatpak --installation=gaming install flathub com.usebottles.bottles&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will take a while depending on your internet speed.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s the thing: while Bottles itself is installed on the other drive&#x2F;partition that you specified in &lt;code&gt;&#x2F;etc&#x2F;flatpak&#x2F;installations.d&#x2F;gaming.conf&lt;&#x2F;code&gt;, it&#x27;s data is still residing on your current Linux partition. We don&#x27;t want that. But first, run Bottles for the first time.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt; flatpak --installation=gaming run com.usebottles.bottles&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;--installation&lt;&#x2F;code&gt; flag is optional if this is the only Bottles you have. Let it do it&#x27;s thing and exit once you&#x27;re on the main screen.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;re going to use symlinks to trick Bottles into storing data elsewhere.&lt;&#x2F;p&gt;
&lt;p&gt;Bottles stores it&#x27;s files at &lt;code&gt;~&#x2F;.var&#x2F;app&#x2F;com.usebottles.bottles&lt;&#x2F;code&gt; (you can check right now if there&#x27;s anything there). We&#x27;re interested in the &lt;code&gt;~&#x2F;.var&#x2F;app&#x2F;com.usebottles.bottles&#x2F;data&lt;&#x2F;code&gt; folder.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt; mv ~&#x2F;.var&#x2F;app&#x2F;com.usebottles.bottles&#x2F;data &#x2F;run&#x2F;media&#x2F;path&#x2F;to&#x2F;your&#x2F;drive&#x2F;flatpak&#x2F;bottles_data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course, the exact path depends on you, it doesn&#x27;t have to be &lt;code&gt;flatpak&#x2F;bottles_data&lt;&#x2F;code&gt;. Let&#x27;s give Bottles permissions to access our new location.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt; sudo flatpak override --installation=gaming --filesystem=&#x2F;run&#x2F;media&#x2F;path&#x2F;to&#x2F;your&#x2F;drive&#x2F;flatpak&#x2F;bottles_data com.usebottles.bottles&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You might not need &lt;code&gt;sudo&lt;&#x2F;code&gt;. Anyway, now&#x27;s the imporant part: we need to symlink &lt;code&gt;&#x2F;run&#x2F;media&#x2F;path&#x2F;to&#x2F;your&#x2F;drive&#x2F;flatpak&#x2F;bottles_data&lt;&#x2F;code&gt; to &lt;code&gt;~&#x2F;.var&#x2F;app&#x2F;com.usebottles.bottles&#x2F;data&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt; ln -s &#x2F;run&#x2F;media&#x2F;path&#x2F;to&#x2F;your&#x2F;drive&#x2F;flatpak&#x2F;bottles_data ~&#x2F;.var&#x2F;app&#x2F;com.usebottles.bottles&#x2F;data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And you&#x27;re done. Run Bottles to see if everything&#x27;s working fine.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-3-running-games&quot;&gt;Step 3: Running games&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;ve noticed that I can&#x27;t access my game files if I don&#x27;t give Bottles permission to read those directories. So I&#x27;m going to show a few examples of how you might go about this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt; sudo flatpak override --installation=gaming&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949FB5;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;	 --filesystem=&#x2F;run&#x2F;media&#x2F;path&#x2F;to&#x2F;your&#x2F;drive&#x2F;Games com.usebottles.bottles&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #737C73;&quot;&gt;# OR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt; sudo flatpak override --installation=gaming&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949FB5;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;	 --filesystem=&#x2F;run&#x2F;media&#x2F;path&#x2F;to&#x2F;your&#x2F;drive&#x2F;Games&#x2F;TES4Oblivion com.usebottles.bottles&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I haven&#x27;t tried setting up Steam because I don&#x27;t own anything that doesn&#x27;t have a native Linux build.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;it-was-worth-it&quot;&gt;It was worth it&lt;&#x2F;h3&gt;
&lt;p&gt;In the end, my Flatpak installation ended up being 6.4G and Bottles data ended up being 3.2G big. And that&#x27;s without any games. I couldn&#x27;t &quot;waste&quot; this much storage on my Linux partition. This was worth it.&lt;&#x2F;p&gt;
</description>
      </item>
      
      
      
      <item>
          <title>What&#x27;s so hard about writing a JSON parser?</title>
          <pubDate>Sun, 19 Jan 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://furtidev.github.io/blog/json-parser/</link>
          <guid>https://furtidev.github.io/blog/json-parser/</guid>
          <description xml:base="https://furtidev.github.io/blog/json-parser/">&lt;p&gt;I always assumed JSON was a complex format to implement, but it&#x27;s quite simple. So simple that you don&#x27;t even need to read RFC 8259 - there&#x27;s a simple, straight to the point webpage denoting JSON in it&#x27;s entirety in just a few lines and some pretty pictures (yay!). If you&#x27;ve never done this before, and want to write a parser for JSON yourself then go to the &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.json.org&#x2F;json-en.html&quot;&gt;JSON spec&lt;&#x2F;a&gt; website and have fun. You&#x27;ll need to learn about some basic concepts as well, such as tokenization, parsing and abstract syntax trees.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll do a overview: Tokenization or lexing, is the process of giving meaning to characters (e.g in Python, the characters &lt;code&gt;f&lt;&#x2F;code&gt;, &lt;code&gt;o&lt;&#x2F;code&gt; &amp;amp; &lt;code&gt;r&lt;&#x2F;code&gt; don&#x27;t mean anything on their own, but together they form the &lt;code&gt;for&lt;&#x2F;code&gt; keyword, this is the job of the lexer). After you&#x27;re done lexing, you&#x27;re left with a bunch of tokens for keywords, number and string literals etc. The tokens themselves can contain additional data, such as the line &amp;amp; column in the original source code from where they came from. More importantly, some tokens do need to hold on to the original value. For example, a &lt;code&gt;NUMBER&lt;&#x2F;code&gt; token should contain the integer value the token was generated from, otherwise that data will be lost. These still don&#x27;t mean anything. Parsing is the process of giving meaning to a stream of tokens by using a data structure to represent the original structure and thus meaning, of the source code. Trees are commonly used to represent source code because they naturally map to the hierarchy of code, referred to as the abstract syntax tree (AST) or parse tree. You may find Wikipedia&#x27;s entry on ASTs helpful but of course, there are plenty of content on the internet about this.&lt;&#x2F;p&gt;
&lt;p&gt;Now, if you don&#x27;t want any more hints, then you should stop reading this blog right here and come back later when you&#x27;re done with your parser and if you want, compare with my approach.&lt;&#x2F;p&gt;
&lt;p&gt;Keep in mind that I&#x27;ll use &lt;code&gt;...&lt;&#x2F;code&gt; to indicate lines of code not shown in the snippets. Also this isn&#x27;t a tutorial on how to write a JSON parser as I&#x27;ll only be talking about what kind of decisions I made on certain aspects. I was learning some Rust a while ago and wanted to test what I had learned so far, so I decided to write my parser in Rust. Tokenization was fairly easy but there are some catches. Numbers in JSON map to JavaScript numbers, so one key feature is scientific notation: &lt;code&gt;10e-5&lt;&#x2F;code&gt; evaluates to &lt;code&gt;0.0001&lt;&#x2F;code&gt;. Rust also supports this, so parsing numbers was really just as simple as capturing the string and casting it to a float.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;tokenizer.rs&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; num_result&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;f64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; = iter&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;once&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;ch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;chain&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;from_fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;||&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4746E;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;by_ref&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;next_if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;            s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;is_ascii_digit&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;                || *&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;                || *&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;E&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;                || *&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;                || *&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;                || *&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;        })&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;    }))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;collect&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;parse&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;String literals took a bit more effort, my tokenizer was getting confused between string literals and &lt;code&gt;true&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;false&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;null&lt;&#x2F;code&gt; values. In JSON, string literals can only begin with double quotes, so I came up with a simple trick, the tokenizer switches to &quot;string parsing mode&quot; when it detects a double quote.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;tokenizer.rs&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; ch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;    &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4746E;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;string_mode &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;= !&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4746E;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;string_mode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;        tokens&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;Token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;Quote&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So, now in the next iteration, the tokenizer checks if &lt;code&gt;string_mode&lt;&#x2F;code&gt; is &lt;code&gt;true&lt;&#x2F;code&gt; and checks to make sure the current token is not a double quote (because that would mean the string literal has ended). I wrote a helper function called &lt;code&gt;make_string()&lt;&#x2F;code&gt; to deal with the parsing. Now, this function is poorly designed or perhaps you could say, it&#x27;s poorly named. Because it also handles the logic for creating &lt;code&gt;true&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;false&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;null&lt;&#x2F;code&gt; tokens. You might wonder why, but it&#x27;s simply because the logic for parsing string literals and these special tokens were quite similar, and I .. got a bit lazy so I merged them into a single function.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;tokenizer.rs&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4746E;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;string_mode &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; ch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; tok&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;Str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4746E;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;make_string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B6927B;&quot;&gt;false&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;));&lt;&#x2F;span&gt;&lt;span style=&quot;color: #737C73;&quot;&gt; &#x2F;&#x2F; false means it&amp;#39;s not a special token but a literal&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;    tokens&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tok&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4746E;&quot;&gt;    self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;advance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;    continue&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; ch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;    &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;        let&lt;&#x2F;span&gt;&lt;span&gt; bool_value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4746E;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;make_string&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B6927B;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; bool_value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt; &amp;quot;true&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;            tokens&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;Token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;Bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B6927B;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt; else if&lt;&#x2F;span&gt;&lt;span&gt; bool_value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt; &amp;quot;false&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;            tokens&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;Token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;Bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B6927B;&quot;&gt;false&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;String literals can also use escape sequences (only a handful are supported by the spec) but fortunately implementing them is trivial. Similar to how if the tokenizer detects a double quote it goes into string parsing mode, this time, if the string parser detects a forward slash (&lt;code&gt;\&lt;&#x2F;code&gt;) - it goes into escape mode.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;tokenizer.rs&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; ident&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; escape_mode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B6927B;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;while let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;ch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4746E;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;peek&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; &amp;amp;&amp;amp; !&lt;&#x2F;span&gt;&lt;span&gt;escape_mode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #737C73;&quot;&gt;        &#x2F;&#x2F; go to escape mode if `\` was detected.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949FB5;&quot;&gt;\\&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;            escape_mode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B6927B;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4746E;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;advance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;            continue&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;        ident&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;ch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4746E;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;advance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt; else if&lt;&#x2F;span&gt;&lt;span&gt; escape_mode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #737C73;&quot;&gt;        &#x2F;&#x2F; parse JSON standard escape codes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;        match&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;ch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;            &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ident&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;ch&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;            &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949FB5;&quot;&gt;\\&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ident&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949FB5;&quot;&gt;\\&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;            &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ident&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;            &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ident&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949FB5;&quot;&gt;\u{0008}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;            &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ident&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949FB5;&quot;&gt;\u{000c}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;            &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ident&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949FB5;&quot;&gt;\u{000a}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;            &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ident&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949FB5;&quot;&gt;\u{000d}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;            &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8A9A7B;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ident&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949FB5;&quot;&gt;\u{0009}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;#39;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span&gt;            _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span&gt;        escape_mode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B6927B;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4746E;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;advance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;30&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color: #737C73;&quot;&gt;        &#x2F;&#x2F; non-escape quote detected, end string.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;        break&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;33&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;34&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;    ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;35&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So with that, the tokenizer is done. If you&#x27;re wondering, here are all the token variants:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;tokenizer.rs&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;pub enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;    LeftBrace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;    RightBrace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;    LeftBracket&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;    RightBracket&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;    Quote&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;    Comma&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;    Colon&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;    Str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;    Number&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;f64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;    Bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;    Null&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;    Eof&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Writing the lexer took me 3 hours, spread across two days. The parser was actually a bit simpler. The hard part was figuring out a coherent structure to represent JSON. Rust is a strictly typed language, I can&#x27;t plop a &lt;code&gt;f64&lt;&#x2F;code&gt; into a &lt;code&gt;bool&lt;&#x2F;code&gt;, the compiler will refuse to compile. But the issue is, JSON doesn&#x27;t have such restrictions, you can put a boolean, a string or a number as values anywhere (except keys, they can only be string literals). Also, JSON files can be as simple as this:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;a_perfectly_valid_json_file.json&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B6927B;&quot;&gt;true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which means the root of a JSON file can be anything, but commonly it&#x27;s an array or a key-value structure (called &lt;em&gt;objects&lt;&#x2F;em&gt; in the spec). Now the question is: how do we represent this dynamic file format in Rust? You see, enums in Rust can hold values and this feature can be used to achieve the dynamism we need. We just need to define an enum with all possible types of values and just refer to the enum type everywhere else - a job well done. To be fair, this isn&#x27;t anything revolutionary. I didn&#x27;t come up with this, it&#x27;s a common practice in Rust.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;parser.rs&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;pub enum&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;    Null&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;    Str&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;    Num&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;f64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;    Bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;    Obj&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;Object&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;    Arr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;Array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I could&#x27;ve mapped JSON objects to a &lt;code&gt;std::collections::HashMap&lt;&#x2F;code&gt; but in the end I went with my own structs for both objects and arrays, their definitions are simple.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;parser.rs&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;pub struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Root&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;    pub&lt;&#x2F;span&gt;&lt;span&gt; child&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;Value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #737C73;&quot;&gt;&#x2F;&#x2F; {... properties ...}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;pub struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Object&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;    pub&lt;&#x2F;span&gt;&lt;span&gt; children&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;Property&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #737C73;&quot;&gt;&#x2F;&#x2F; [... any values ...]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;pub struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;    pub&lt;&#x2F;span&gt;&lt;span&gt; children&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;Value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #737C73;&quot;&gt;&#x2F;&#x2F; &amp;quot;key&amp;quot;: value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;pub struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Property&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;    pub&lt;&#x2F;span&gt;&lt;span&gt; lhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;    pub&lt;&#x2F;span&gt;&lt;span&gt; rhs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As you can see, wherever JSON allows any valid value, we put our newly created enum &lt;code&gt;Value&lt;&#x2F;code&gt; as the type. The parser starts by creating a root node and iterating through the tokens. Parsing needs to be recursive when you have things that can contain themselves (e.g an array can contain more arrays), so keeping this in mind, we determine the root value, and if it&#x27;s an array or an object, we call their respective parsing functions, this easily helps to make the entire process recursive because within those functions we call the parsing functions again if we detect arrays or objects, and so on and so forth. Now, I got a bit lazy again and did a lot of code duplication for each of these functions, and there are nicer ways to do it but I had already crossed the deadline I set for myself so some corners were cut.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;parser.rs&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C5C9C5; background-color: #181616;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt; parse&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4746E;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Root&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Root&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Root&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;span&gt; child&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;    while let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;tok&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4746E;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;curr_tok&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;clone&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;        match&lt;&#x2F;span&gt;&lt;span&gt; tok&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;            ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;            Token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;LeftBracket&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;                let&lt;&#x2F;span&gt;&lt;span&gt; array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4746E;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;parse_array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;                root&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;child &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;Value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;Arr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;array&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;            Token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;LeftBrace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8992A7;&quot;&gt;                let&lt;&#x2F;span&gt;&lt;span&gt; object&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4746E;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;parse_object&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;                root&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;child &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EA4A2;&quot;&gt;Value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8BA4B0;&quot;&gt;Obj&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;object&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;            ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C4B28A;&quot;&gt;        ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;19&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;    root&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #625E5A;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9E9B93;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So those were all the necessary puzzles that needed to be solved, and soon enough I had a functioning parser. I haven&#x27;t benchmarked it but it&#x27;s definitely not faster than production grade parsers written in Rust. This is a rather naive implementation. So I&#x27;ve accurately named it: &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;furtidev&#x2F;dumb_json_parser&quot;&gt;furtidev&#x2F;dumb_json_parser&lt;&#x2F;a&gt;. Take a look at the GitHub repo if you are interested in all the code. I wrote an example app where I was directly using the &quot;tree&quot; and I noticed a lot of repetition. Perhaps it can be quite nice to use if I add some high-level APIs. Perhaps another time. Recreational projects like these are fun to work on and I have a few lined up, hopefully when they&#x27;re done I can write about them too. Goodnight.&lt;&#x2F;p&gt;
&lt;center style=&quot;margin-bottom: 10px&quot;&gt;&lt;img src=&quot;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;furtidev&amp;#x2F;dumb_json_parser&amp;#x2F;raw&amp;#x2F;main&amp;#x2F;assets&amp;#x2F;tweet.png&quot; width=&quot;70%&quot; height=&quot;70%&quot; style=&quot;border: 1px solid #9c807e; border-radius: 5px&quot;&#x2F;&gt; &lt;br&gt; &lt;span style=&quot;color: #9c807e; font-style: italic&quot;&gt;@TheGingerBill: If you cannot write a parser for JSON from scratch: you need to learn how to do that NOW!&lt;&#x2F;span&gt;&lt;&#x2F;center&gt;
</description>
      </item>
      
      
      
      
      
      
      <item>
          <title>Trying Ghostty: My experience with terminal emulators</title>
          <pubDate>Sun, 10 Nov 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://furtidev.github.io/blog/ghostty-testing/</link>
          <guid>https://furtidev.github.io/blog/ghostty-testing/</guid>
          <description xml:base="https://furtidev.github.io/blog/ghostty-testing/">&lt;h1 id=&quot;childhood&quot;&gt;Childhood&lt;&#x2F;h1&gt;
&lt;p&gt;I first started programming on an Android phone, basically running a PHP 7.x and MySQL 5.x server (I couldn&#x27;t find the app I was using for that at the time) and using a barebones text editor (it was probably &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;play.google.com&#x2F;store&#x2F;apps&#x2F;details?id=com.rhmsoft.edit.pro&quot;&gt;this one&lt;&#x2F;a&gt;). I didn&#x27;t need to interact with terminals. That all changed in 2021, when I was using the terminal more frequently. As far as terminal emulation goes, I just used the basic Command Line, yeah, the Windows one - yikes. I can&#x27;t imagine how I programmed on Windows.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;adolescence&quot;&gt;Adolescence&lt;&#x2F;h1&gt;
&lt;p&gt;But after some time, I found &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;alacritty.org&#x2F;&quot;&gt;Alacritty&lt;&#x2F;a&gt;. It was fast, it made me feel cool. I installed all the hip stuff, like &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;starship.rs&#x2F;&quot;&gt;Starship&lt;&#x2F;a&gt; prompt. But Alacritty had no support for tabs and I &lt;em&gt;love&lt;&#x2F;em&gt; organizing things via tabs. So it was inconvenient and on top of that, after going through &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;alacritty&#x2F;alacritty&#x2F;issues&#x2F;3129&quot;&gt;this discourse&lt;&#x2F;a&gt; on their GitHub, I guess it&#x27;s safe to say that Alacritty will never have tabs. From this thread and some googling, I learned about Kovid Goyal&#x27;s &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sw.kovidgoyal.net&#x2F;kitty&#x2F;&quot;&gt;kitty terminal emulator&lt;&#x2F;a&gt; - but I was disappointed because &lt;code&gt;kitty&lt;&#x2F;code&gt; wasn&#x27;t on Windows. Okay, I guess I&#x27;ll use a terminal multiplexer.. oh no I can&#x27;t - neither &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;zellij.dev&#x2F;&quot;&gt;zellij&lt;&#x2F;a&gt; nor tmux are natively supported on Windows. I think I did try &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.google.com&#x2F;search?client=firefox-b-d&amp;amp;q=wezterm&quot;&gt;Wezterm&lt;&#x2F;a&gt; somewhere along the way, but it didn&#x27;t stick for long.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;redemption&quot;&gt;Redemption&lt;&#x2F;h1&gt;
&lt;p&gt;On 13th of January, 2023 (yes, I noted down the exact date), I switched to Linux. That means I could finally use &lt;code&gt;kitty&lt;&#x2F;code&gt;. But I had a thought.. what if I just use Alacritty with &lt;code&gt;zellij&lt;&#x2F;code&gt;? I did that for a bit and couldn&#x27;t get used to using a terminal multiplexer for tabs, so - &lt;code&gt;kitty&lt;&#x2F;code&gt; it is. So all in all, I&#x27;ve used &lt;code&gt;kitty&lt;&#x2F;code&gt; for quite some time up until a &lt;strong&gt;ghost&lt;&#x2F;strong&gt; started haunting me. Before moving on to talking about that, &lt;code&gt;kitty&lt;&#x2F;code&gt; deserves some words. I like it a lot - with the occassional &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sw.kovidgoyal.net&#x2F;kitty&#x2F;faq&#x2F;#i-get-errors-about-the-terminal-being-unknown-or-opening-the-terminal-failing-or-functional-keys-like-arrow-keys-don-t-work&quot;&gt;SSH ragequit&lt;&#x2F;a&gt;, you could say it was a love-hate relationship, majority of it being love though. But anyway, I&#x27;m supposed to talk about .. the hauntings of a ghost.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;enter-ghostty&quot;&gt;Enter Ghostty&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;mitchellh.com&#x2F;&quot;&gt;Mitchell Hashimoto&lt;&#x2F;a&gt;. You might know him. He&#x27;s just this niche guy, &lt;em&gt;&lt;strong&gt;co-founder of &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.hashicorp.com&#x2F;&quot;&gt;HashiCorp&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;. So, when he announced that he was working on a terminal emulator written fully in Zig - there was hype. This was the light in the darkness, as Warp (no, I don&#x27;t feel like linking Warp) receives $73M in funding for their terminal emulator where you have to log in, yes, log in to use your terminal, the coming of Ghostty showed light to the believers.&lt;&#x2F;p&gt;
&lt;p&gt;Ghostty is still in private beta, with a &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;mitchellh.com&#x2F;writing&#x2F;ghostty-is-coming&quot;&gt;1.0 release&lt;&#x2F;a&gt; coming in December, 2024. Mark your calendars, folks. I got invited into the private beta right before Halloween, so it fits.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;purpose&quot;&gt;Purpose&lt;&#x2F;h3&gt;
&lt;p&gt;But why does Ghostty exist? There are a few key reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Native UI&lt;&#x2F;strong&gt;. It uses GTK on Linux and SwiftUI on MacOS. This also means native tabs support. While &lt;code&gt;kitty&lt;&#x2F;code&gt; does support tabs, it doesn&#x27;t use native widgets.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Extremely fast&lt;&#x2F;strong&gt;, often beating Alacritty.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Feature-rich&lt;&#x2F;strong&gt;. Supports kitty image protocol, native support for emojis, built-in terminal inspector for rich terminal debugging etc.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Most importantly&lt;&#x2F;strong&gt;, all of this in a &lt;em&gt;complete&lt;&#x2F;em&gt; cross-platform package. Before Ghostty, there wasn&#x27;t a single terminal emulator that had all of the aforementioned perks. See figure 1 &amp;amp; 2 below for a summary.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;center style=&quot;margin-bottom: 10px&quot;&gt;&lt;img src=&quot;.&amp;#x2F;figure-1.webp&quot; width=&quot;70%&quot; height=&quot;70%&quot; style=&quot;border: 1px solid #9c807e; border-radius: 5px&quot;&#x2F;&gt; &lt;br&gt; &lt;span style=&quot;color: #9c807e; font-style: italic&quot;&gt;Figure 1: Chart comparing popular terminal emulators with Ghostty&lt;&#x2F;span&gt;&lt;&#x2F;center&gt;
&lt;center style=&quot;margin-bottom: 10px&quot;&gt;&lt;img src=&quot;.&amp;#x2F;figure-2.webp&quot; width=&quot;70%&quot; height=&quot;70%&quot; style=&quot;border: 1px solid #9c807e; border-radius: 5px&quot;&#x2F;&gt; &lt;br&gt; &lt;span style=&quot;color: #9c807e; font-style: italic&quot;&gt;Figure 2: Core purpose of Ghostty.&lt;&#x2F;span&gt;&lt;&#x2F;center&gt;
&lt;center style=&quot;margin-bottom: 10px&quot;&gt;&lt;img src=&quot;.&amp;#x2F;tabs_one.png&quot; width=&quot;70%&quot; height=&quot;70%&quot; style=&quot;border: 1px solid #9c807e; border-radius: 5px&quot;&#x2F;&gt; &lt;br&gt; &lt;span style=&quot;color: #9c807e; font-style: italic&quot;&gt;Native tabs, using GTK on Linux&lt;&#x2F;span&gt;&lt;&#x2F;center&gt;
&lt;center style=&quot;margin-bottom: 10px&quot;&gt;&lt;img src=&quot;.&amp;#x2F;kitty_image_protocol.png&quot; width=&quot;70%&quot; height=&quot;70%&quot; style=&quot;border: 1px solid #9c807e; border-radius: 5px&quot;&#x2F;&gt; &lt;br&gt; &lt;span style=&quot;color: #9c807e; font-style: italic&quot;&gt;Image rendering using Kitty Image Protocol (image: NCR Veteran Ranger Helmet)&lt;&#x2F;span&gt;&lt;&#x2F;center&gt;
&lt;center style=&quot;margin-bottom: 10px&quot;&gt;&lt;img src=&quot;.&amp;#x2F;terminal_inspector.png&quot; width=&quot;70%&quot; height=&quot;70%&quot; style=&quot;border: 1px solid #9c807e; border-radius: 5px&quot;&#x2F;&gt; &lt;br&gt; &lt;span style=&quot;color: #9c807e; font-style: italic&quot;&gt;Built-in terminal inspector for TUI debugging&lt;&#x2F;span&gt;&lt;&#x2F;center&gt;
&lt;p&gt;What more could one ask for?! Well, as it turns out.. a lot more. Ghostty wants to be the browser-equivalent for TUIs (terminal user interface). It wants to have native support for progress bars, context menus, drag &amp;amp; drop, mouse gestures and so much more - a complete platform for text based user interfaces. I mean, that&#x27;s A LOT to take in, even though these are long-term goals. It&#x27;s ambitious, it&#x27;s exciting, and finally there&#x27;s someone willing to bring innovations to the terminal.&lt;&#x2F;p&gt;
&lt;p&gt;At the core of Ghostty, there&#x27;s &lt;code&gt;libghostty&lt;&#x2F;code&gt;, a cross-platform library that powers Ghostty. I like where they&#x27;re going with this, essentially you can use libghostty to ship whatever you want: standalone TUI applications, embedding Ghostty in other places and even getting a terminal emulator running on the web, seems like your imagination is the limit. Ghostty itself is a software using libghostty. Sort of like how the Godot game engine is a Godot &quot;game&quot;. &lt;code&gt;libghostty&lt;&#x2F;code&gt; will eventually be available as a standlone library, and I&#x27;m excited for that - it exposes a C api so you can use whatever language you want with it as long as it can interface with C.&lt;&#x2F;p&gt;
&lt;p&gt;Even though it currently only supports MacOS and Linux, Windows support is planned for sometime after the 1.0 release. I&#x27;ll shed a tear when that happens, considering the pain I had to go through to find an appropriate terminal emulator for my needs on Windows.&lt;&#x2F;p&gt;
&lt;p&gt;So even though I was a bit confused by why Ghostty needs to exist at first, I&#x27;m now completely sold. And to be completely honest, &lt;em&gt;you&lt;&#x2F;em&gt; should be too.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;daily-driving&quot;&gt;Daily driving&lt;&#x2F;h3&gt;
&lt;p&gt;Ever since I got access to the private beta, Ghostty has been my daily driver. Sorry cat terminal. Apart from some weird issues here and there which I reported, it has been fantastic. The community is friendly, there&#x27;s an active group of developers writing TUIs on Ghostty and some are contributing to the project itself. Point is, Ghostty gets out of the way and lets me do my work peacefully. I also giggle once in a while thinking a ghost is watching me while I run my commands. So if you were wondering if it&#x27;s ready for some rigorous daily use, now you know.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m not an avid recompiler, in fact I haven&#x27;t recompiled Ghostty ever since. I should really do it one of these days.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h1&gt;
&lt;p&gt;Need I say more? I&#x27;m sure I&#x27;ve gotten my point across, yes, Ghostty is good. You should use it when it&#x27;s out. Also, why not &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;discord.gg&#x2F;ghostty&quot;&gt;join the Discord&lt;&#x2F;a&gt;? I forgot to mention a &lt;em&gt;killer&lt;&#x2F;em&gt; feature: shaders. I wrote a small TUI to make the best use of it (if you can&#x27;t tell, I&#x27;ve been playing a lot of Fallout: New Vegas):&lt;&#x2F;p&gt;
&lt;center style=&quot;margin-bottom: 10px&quot;&gt;&lt;img src=&quot;.&amp;#x2F;fallout_terminal.png&quot; width=&quot;70%&quot; height=&quot;70%&quot; style=&quot;border: 1px solid #9c807e; border-radius: 5px&quot;&#x2F;&gt; &lt;br&gt; &lt;span style=&quot;color: #9c807e; font-style: italic&quot;&gt;I got spurs that jingle, jangle, jingle&lt;&#x2F;span&gt;&lt;&#x2F;center&gt;
&lt;p&gt;There&#x27;s also a repository for Ghostty shaders: &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;hackrmomo&#x2F;ghostty-shaders&quot;&gt;hackrmomo&#x2F;ghostty-shaders&lt;&#x2F;a&gt;. And lastly:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Childhood: Clueless early days of programming.&lt;&#x2F;li&gt;
&lt;li&gt;Adolescence: Still clueless, but pretending to be wise using Windows for development.&lt;&#x2F;li&gt;
&lt;li&gt;Redemption: Making up for my past crimes and switching to Linux.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Also, I can&#x27;t wait to actually contribute to Ghostty someday, but that&#x27;s for another time. For now, I gotta take a nap. This blog took &lt;em&gt;[calculates time]&lt;&#x2F;em&gt; at least 3 hours. Goodbye, Good Night, Oyasumi and everything else.&lt;&#x2F;p&gt;
</description>
      </item>
      
      
      <item>
          <title>My experience with password managers</title>
          <pubDate>Mon, 11 Sep 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://furtidev.github.io/blog/my-experience-with-password-managers/</link>
          <guid>https://furtidev.github.io/blog/my-experience-with-password-managers/</guid>
          <description xml:base="https://furtidev.github.io/blog/my-experience-with-password-managers/">&lt;p&gt;Back when I was a foolish young man, I used the same password everywhere so that I won&#x27;t have to struggle with remembering what password I set for what account. In retrospect, that was a very, very stupid decision. And as you can guess, I got &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;haveibeenpwned.com&#x2F;&quot;&gt;pwned&lt;&#x2F;a&gt;!&lt;&#x2F;p&gt;
&lt;p&gt;So after that I finally decided to use a password manager. So I&#x27;ll be sharing my experience with the ones I&#x27;ve used so far.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;lastpass-don-t&quot;&gt;LastPass (don&#x27;t)&lt;&#x2F;h2&gt;
&lt;p&gt;I chose LastPass at first because Daddy Google had it on top of the search results when I looked up &#x27;Best Password Manager&#x27;. I was using it until LastPass had a data breach last year, it was a huge mess. A few months later the company revealed that GoTo&#x27;s (the company behind LastPass) other services were also attacked, plus encrypted backups &lt;strong&gt;with encryption keys for said backups&lt;&#x2F;strong&gt; and MFA data were also stolen.&lt;&#x2F;p&gt;
&lt;p&gt;GoTo didn&#x27;t give any more details about it, like how old the backups were etc. LastPass is a horrible service. GoTo is a horrible company, the handled the breach very poorly. Constantly getting spammed with promotional e-mails was also very annoying. I just exported all my data, changed all my passwords and switched to BitWarden.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bitwarden-great&quot;&gt;BitWarden (great)&lt;&#x2F;h2&gt;
&lt;p&gt;I just said to myself, &quot;Heh, it can&#x27;t be worse than LastPass&quot;, and went in. First of all, BitWarden is open source on &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bitwarden&#x2F;&quot;&gt;GitHub&lt;&#x2F;a&gt;. I used the free plan but the personal premium plan is also great, only $10&#x2F;year. Unlike LastPass, BitWarden actually encrypts all your fields. I had a very strong and long (that&#x27;s... what... she.... said....) master password.&lt;&#x2F;p&gt;
&lt;p&gt;Regular security audits conducted by notable third-party security firms, open source, self-hostable, generous free plan, transparent company, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bitwarden.com&#x2F;help&#x2F;what-encryption-is-used&#x2F;&quot;&gt;zero knowledge encryption&lt;&#x2F;a&gt; (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bitwarden.com&#x2F;resources&#x2F;zero-knowledge-encryption-white-paper&#x2F;&quot;&gt;white paper&lt;&#x2F;a&gt;), good reputation and I like their philosophy towards security.&lt;&#x2F;p&gt;
&lt;p&gt;BitWarden one day randomly locked me out of my account with the following error: &quot;Traffic from your network looks unusual&quot; - why? I don&#x27;t know! But either way, it was enough of a reason to not use BitWarden anymore.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;keepassxc-currently-using-great&quot;&gt;KeePassXC (currently using, great)&lt;&#x2F;h2&gt;
&lt;p&gt;I currently use KeePassXC. There&#x27;s no server involved, you just download KeePassXC and start using it. Importing data from BitWarden wasn&#x27;t hard though it wasn&#x27;t seamless either. I just save regular backups of my database on the cloud, and use a strong master password. Plus, you can also use YubiKey and OnlyKey for extra protection. It is also open source software and I like that everything about it is handled by me and me only. I also use it for OTP.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m no encryption&#x2F;security specialist, I just wanted to share my experience so if I&#x27;ve made any mistakes then comment below or send me an email on: &lt;a href=&quot;mailto:furtidev@tuta.io&quot;&gt;furtidev@tuta.io&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
      
    </channel>
</rss>
