<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Thiago Massari Guedes</title>
    <description>The latest articles on Forem by Thiago Massari Guedes (@thiagomg).</description>
    <link>https://forem.com/thiagomg</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F145697%2Ff09754e6-4e55-40b1-b662-386efad39570.jpg</url>
      <title>Forem: Thiago Massari Guedes</title>
      <link>https://forem.com/thiagomg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/thiagomg"/>
    <language>en</language>
    <item>
      <title>Bringing my old MacBook Pro 8,2 back to life (again)</title>
      <dc:creator>Thiago Massari Guedes</dc:creator>
      <pubDate>Mon, 09 Feb 2026 03:01:44 +0000</pubDate>
      <link>https://forem.com/thiagomg/bringing-my-old-macbook-pro-82-back-to-life-again-4lpi</link>
      <guid>https://forem.com/thiagomg/bringing-my-old-macbook-pro-82-back-to-life-again-4lpi</guid>
      <description>&lt;p&gt;(This is a continuation of the previous post "Bringing my old MacBook Pro 8,2 back to life")&lt;/p&gt;

&lt;p&gt;I brought my old MacBook pro 2011 back to life, after years collecting dust in my garage, running Linux Mint beautifully. Fast and modern, but...&lt;/p&gt;




&lt;p&gt;If I managed to get it working with Linux, I probably could get it working with OSX too. I decided, then, to get it back to life and using OSX Snow Leopard - the operating system it came with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing using the original disc
&lt;/h2&gt;

&lt;p&gt;When I tried to run the original installer, it access the GPU right away causing those weird rendering issues. With some searching, I found that I could set a nvram variable to disable the dedicated GPU. On Linux I ran (I am almost sure that was the command):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\x07\x00\x00\x00\x01\x00\x00\x00'&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /sys/firmware/efi/efivars/gpu-power-prefs-fa4ce28d-b62f-4c99-9cc3-6815686e30f9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It worked and I got OSX Snow Leopard installed. I had a goal in my mind - being able to access my website using some web browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  Did it work?
&lt;/h3&gt;

&lt;p&gt;Of course not.&lt;/p&gt;

&lt;p&gt;My WiFi network was not supported by that old mac version. After seeing that using that was going to be quite a lot of work, I decided to see what was the oldest version that would work.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Upgrading to the next release
&lt;/h3&gt;

&lt;p&gt;When I started upgrading to Mac OSX Lion, instead of holding Option key (&lt;code&gt;⌥&lt;/code&gt;), I pressed Command (&lt;code&gt;⌘&lt;/code&gt;) + Option (&lt;code&gt;⌥&lt;/code&gt;) + P + R and my nvram trick was gone.&lt;/p&gt;

&lt;p&gt;After some more searching, I found that I could boot using Command (&lt;code&gt;⌘&lt;/code&gt;) + S and boot to single user text mode. When there, I had to run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nvram fa4ce28d-b62f-4c99-9cc3-6815686e30f9:gpu-power-prefs&lt;span class="o"&gt;=&lt;/span&gt;%01%00%00%00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would make the installer boot, but not the installed version.&lt;/p&gt;

&lt;p&gt;To be able to boot into the newly installed OSX Lion - after some more research, I found that I could just delete the radeon drivers. As I deleted incorrect things and had to do this a few times again, I started to move the drivers and restore. Also, every update (Yes! Even Snow Leopard had Apple Software updates working), the drivers were back. Anyway, after many times, I found exactly what to do. I created a bkp directory and ran every software update and every OS upgrade:&lt;/p&gt;

&lt;p&gt;This is the /System/Library/Extensions/ of the installed drive&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /Volumes/Thiago-MBP/bkp
&lt;span class="nb"&gt;mv&lt;/span&gt; ../System/Library/Extensions/&lt;span class="k"&gt;*&lt;/span&gt;Radeon&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eventually in OSX Mavericks (AFAIR), I got WiFi working, but Safari was still not recognising modern certificates&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Upgrading jorney
&lt;/h2&gt;

&lt;p&gt;At some point, I thought: I had everything working nicely with Linux Mint - and then I decided to go back to something outdated and full of issues as even new software does not support those old OSX versions and new OSX versions don't support my old Mac. &lt;strong&gt;Why do I do that to me?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Anyway, thanks to Internet Archive and lots of patience, I found all the OS installers I needed. I installed and upgraded to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Snow Leopard&lt;/li&gt;
&lt;li&gt;Lion&lt;/li&gt;
&lt;li&gt;Mountain Lion&lt;/li&gt;
&lt;li&gt;Mavericks&lt;/li&gt;
&lt;li&gt;Yosemite&lt;/li&gt;
&lt;li&gt;El Capitan&lt;/li&gt;
&lt;li&gt;Sierra&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And when I got to Sierra&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FINALLY!!!&lt;/strong&gt;&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Is it better than the Linux Mint experience?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;No.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Interesting, I found that Youtube is not flaky using this version of OSX + Firefox and it was with Mint. Everything else was better, much better on Linux.&lt;/p&gt;

&lt;p&gt;Getting any tool installed was harder as everything dropped support for OSX Sierra. I had to compile most of the tools from source (Luckily not Firefox) and remembered how nice is TextMate - which I am using right now to write this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;I am trying to decide if I will stick with OSX here or try something different, such as FreeBSD or WindowMakerLive.&lt;/p&gt;

&lt;p&gt;Let's see&lt;/p&gt;

&lt;p&gt;Original post: &lt;a href="https://thiagocafe.com/view/20260209_bringing_my_old_macbook_pro_82_back_to_life_again/" rel="noopener noreferrer"&gt;https://thiagocafe.com/view/20260209_bringing_my_old_macbook_pro_82_back_to_life_again/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>apple</category>
      <category>macbook</category>
      <category>vintage</category>
    </item>
    <item>
      <title>Bringing my old MacBook Pro 8,2 back to life</title>
      <dc:creator>Thiago Massari Guedes</dc:creator>
      <pubDate>Sun, 08 Feb 2026 04:24:20 +0000</pubDate>
      <link>https://forem.com/thiagomg/bringing-my-old-macbook-pro-82-back-to-life-2odn</link>
      <guid>https://forem.com/thiagomg/bringing-my-old-macbook-pro-82-back-to-life-2odn</guid>
      <description>&lt;p&gt;This is my old MacBook Pro 8,2 2011. It was in my garage collecting dust after it's dedicated GPU got toasted. I am not great with electronics, so replacing the soldered Radeon GPU was not something I thought I'd ever do.&lt;/p&gt;

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

&lt;p&gt;(Sorry, there are way too many images. I added, however, a link to my blog this time)&lt;/p&gt;

&lt;p&gt;Full content: &lt;br&gt;
&lt;a href="https://thiagocafe.com/view/20260208_bringing_my_old_macbook_pro_82_back_to_life" rel="noopener noreferrer"&gt;https://thiagocafe.com/view/20260208_bringing_my_old_macbook_pro_82_back_to_life&lt;/a&gt;&lt;/p&gt;

</description>
      <category>apple</category>
      <category>macbook</category>
      <category>vintage</category>
    </item>
    <item>
      <title>Compiling Window Maker in a Debian-based OS</title>
      <dc:creator>Thiago Massari Guedes</dc:creator>
      <pubDate>Mon, 17 Nov 2025 00:12:12 +0000</pubDate>
      <link>https://forem.com/thiagomg/compiling-window-maker-in-a-debian-based-os-1n87</link>
      <guid>https://forem.com/thiagomg/compiling-window-maker-in-a-debian-based-os-1n87</guid>
      <description>&lt;p&gt;I wanted to study Window Maker source code and change a few things. To do that, I need to compile it from source and change ligthdm to use my custom compiled version.&lt;/p&gt;

&lt;p&gt;Unfortunately, there is not much documentation about compiling Window Maker from source, so I am adding it here so others (and myself in the future) can reuse this.&lt;/p&gt;

&lt;h2&gt;
  
  
  First: Install dependencies
&lt;/h2&gt;

&lt;p&gt;Start by installing deb packages needed to compile Window Maker&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build tools&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;build-essential &lt;span class="se"&gt;\&lt;/span&gt;
     autoconf automake libtool gettext git

&lt;span class="c"&gt;# Base libraries&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;libx11-dev libsm-dev &lt;span class="se"&gt;\&lt;/span&gt;
    libpango1.0-dev libbsd-dev

&lt;span class="c"&gt;# Image libraries&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;libxft-dev libfontconfig-dev libfreetype6-dev &lt;span class="se"&gt;\&lt;/span&gt;
libxpm-dev libjpeg-dev libpng-dev libtiff-dev libgif-dev libwebp-dev &lt;span class="se"&gt;\&lt;/span&gt;

&lt;span class="c"&gt;# Imagemagick library support&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;libmagickwand-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create the alternative installation directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /opt/wmaker
&lt;span class="c"&gt;# Optionally, change ownership to your user to simplify later changes&lt;/span&gt;
&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;:&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; /opt/wmaker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Compiling Window Maker
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://repo.or.cz/wmaker-crm.git
&lt;span class="nb"&gt;cd &lt;/span&gt;wmaker-crm

./configure &lt;span class="nt"&gt;--prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/opt/wmaker &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--enable-modelock&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--enable-pango&lt;/span&gt;

make &lt;span class="nt"&gt;-j&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;nproc&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# add sudo if you didn't change /opt/wmaker ownership&lt;/span&gt;
make &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="c"&gt;# or if you don't want debug symbols (results are 5MiB binaries)&lt;/span&gt;
make install-strip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuring LightDM to use custom Window Maker
&lt;/h2&gt;

&lt;p&gt;And last, let's create a custom session file to select our custom Window Maker&lt;/p&gt;

&lt;p&gt;Edit with your favorite text editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;edit /usr/share/xsessions/wmaker-custom.desktop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[Desktop Entry]&lt;/span&gt;
&lt;span class="py"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Window Maker Custom&lt;/span&gt;
&lt;span class="py"&gt;Comment&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Use Window Maker from /opt/wmaker&lt;/span&gt;
&lt;span class="py"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/opt/wmaker/bin/wmaker&lt;/span&gt;
&lt;span class="py"&gt;Icon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;wmaker&lt;/span&gt;
&lt;span class="py"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;XSession&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; /etc/init.d/lightdm restart
&lt;span class="c"&gt;# or&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart lightdm.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all. Now you can enjoy your own compiled version of Window Maker&lt;/p&gt;

&lt;h3&gt;
  
  
  Post in the author's blog
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://thiagocafe.com/view/20251116_compiling_window_maker_in_a_debianbased_os/" rel="noopener noreferrer"&gt;Compiling Window Maker in a Debian-based OS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>linux</category>
      <category>opensource</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Fixing emoji support in the Linux terminal</title>
      <dc:creator>Thiago Massari Guedes</dc:creator>
      <pubDate>Mon, 17 Nov 2025 00:09:12 +0000</pubDate>
      <link>https://forem.com/thiagomg/fixing-emoji-support-in-the-linux-terminal-34og</link>
      <guid>https://forem.com/thiagomg/fixing-emoji-support-in-the-linux-terminal-34og</guid>
      <description>&lt;p&gt;Recently, tired of the huge accidental complexity of Gnome and KDE, I decided to switch back to Window Maker (again). Being a big terminal user, when I was setting up the terminal, I noticed that emojis were not being displayed correctly by Starship prompt.&lt;/p&gt;

&lt;p&gt;First thing, I installed Nerd Fonts from their website &lt;a href="https://www.nerdfonts.com" rel="noopener noreferrer"&gt;nerdfonts.com&lt;/a&gt;. Guess what - no emojis.&lt;/p&gt;

&lt;p&gt;Then, digging a bit more, I found that some emojis were being displayed properly, but curiously the ones being displayed by Starship prompt were all missing.&lt;/p&gt;

&lt;p&gt;To my luck, there is a deb package that contains all the Emojis and can be used as a fallback for missing emojis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;fonts-noto-color-emoji
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After installing it and restarting the terminal, I got all emojis being properly rendered.&lt;/p&gt;

&lt;p&gt;Finally an easy one.&lt;/p&gt;




&lt;h3&gt;
  
  
  Post in the author's blog
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://thiagocafe.com/view/20251116_fixing_emoji_support_in_the_linux_terminal/" rel="noopener noreferrer"&gt;Fixing emoji support in the Linux terminal&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cli</category>
      <category>linux</category>
      <category>tooling</category>
      <category>debian</category>
    </item>
    <item>
      <title>LuSH 0.15 with syntax sugar</title>
      <dc:creator>Thiago Massari Guedes</dc:creator>
      <pubDate>Sun, 06 Jul 2025 22:01:52 +0000</pubDate>
      <link>https://forem.com/thiagomg/lush-015-with-syntax-sugar-4f8a</link>
      <guid>https://forem.com/thiagomg/lush-015-with-syntax-sugar-4f8a</guid>
      <description>&lt;p&gt;This new release of LuSH brings some interesting and important improvements (not officially supported by LUA), being:&lt;/p&gt;

&lt;h3&gt;
  
  
  String interpolation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Thiago"&lt;/span&gt;
&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"My name is ${name}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  String split
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"string with spaces"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Shell exec
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Lush scripts:"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ls&lt;/span&gt; &lt;span class="n"&gt;scripts&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="n"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;".lush"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;outputs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lush scripts:
mod1.lush
test2.lush
test3.lush
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Subshell exec
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Lush scripts, again:"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;scripts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;ls&lt;/span&gt; &lt;span class="n"&gt;scripts&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="n"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;".lush"&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;tok&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scripts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;ipairs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="s1"&gt;': '&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;outputs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lush scripts, again:
1: mod1.lush
2: test2.lush
3: test3.lush
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Installing:
&lt;/h2&gt;

&lt;p&gt;To install, simply run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;install &lt;/span&gt;lush
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>lua</category>
      <category>rust</category>
    </item>
    <item>
      <title>OpenCV cv::Mat without copying and weird memory ownership</title>
      <dc:creator>Thiago Massari Guedes</dc:creator>
      <pubDate>Thu, 01 May 2025 02:02:59 +0000</pubDate>
      <link>https://forem.com/thiagomg/opencv-cvmat-without-copying-and-weird-memory-ownership-37cj</link>
      <guid>https://forem.com/thiagomg/opencv-cvmat-without-copying-and-weird-memory-ownership-37cj</guid>
      <description>&lt;p&gt;Recently I found an interesting OpenCV behaviour.&lt;/p&gt;

&lt;p&gt;OpenCV &lt;code&gt;cv::Mat&lt;/code&gt; is built to be easy to use. It will allocate, free and reallocate it's own internal data. That's fine for most of the uses, but what if you are sensitive to extra memory allocations?&lt;/p&gt;

&lt;p&gt;As you might expect, C++ developers very often track the memory ownership of any allocated piece of memory, especially when copying memory is not an option. &lt;/p&gt;

&lt;p&gt;To use &lt;code&gt;cv::Mat&lt;/code&gt; without copying the buffer, you can use this class constructor that does not own the memory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Mat&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Mat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;Size&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AUTO_STEP&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the constructor documentation, you can read:&lt;/p&gt;

&lt;p&gt;Pointer to the user data. Matrix constructors ... do not allocate matrix data. Instead, ... which means that no data is copied. ... &lt;strong&gt;The external data is not automatically deallocated, so you should take care of it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So far, so good, let's see if this is true&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Mat&lt;/span&gt; &lt;span class="n"&gt;original_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;imread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;uint8_t&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;image_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;original_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;original_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Mat&lt;/span&gt; &lt;span class="nf"&gt;gray_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;original_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;original_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CV_8UC1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cvtColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;original_image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gray_image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;COLOR_BGR2GRAY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AFTER: cv::Mat data: %p&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AFTER: image_data data: %p&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gray_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It prints&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AFTER: cv::Mat data: 0x138168000
AFTER: image_data data: 0x138168000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, that's great. The data is the same. However, what happens if the given data array is not big enough?&lt;/p&gt;

&lt;p&gt;Let's change the example to remove one byte of the size.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Mat&lt;/span&gt; &lt;span class="nf"&gt;gray_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;original_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;original_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cols&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CV_8UC1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Surprisingly it works. Why?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cvtColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InputArray&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OutputArray&lt;/span&gt; &lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I found that OutputArray, when the allocated data is not big enough, allocates a new array - and that's where I found the surprise. If the data is not owned by cv::Mat, the pointer is &lt;strong&gt;silently replaced by a new allocated one&lt;/strong&gt;, owned by cv::Mat&lt;/p&gt;

&lt;p&gt;If I run the example again, let's see the addresses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AFTER: cv::Mat data: 0x160168000
AFTER: image_data data: 0x1601e0000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In conclusion, if you are using cv::Mat providing the memory yourself, you need to be sure the allocated buffer is enough, and preferably also check the image.data to verify if the provided buffer was used.&lt;/p&gt;

&lt;p&gt;Original post: &lt;a href="https://www.thiagocafe.com/view/20250430_opencv_mat_weird_ownership/" rel="noopener noreferrer"&gt;thiagocafe/OpenCV Mat without copying and weird memory ownership&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>opencv</category>
    </item>
    <item>
      <title>Using flutter with native resources on apple silicon processors</title>
      <dc:creator>Thiago Massari Guedes</dc:creator>
      <pubDate>Fri, 20 Dec 2024 05:53:07 +0000</pubDate>
      <link>https://forem.com/thiagomg/using-flutter-with-native-resources-on-apple-silicon-processors-403g</link>
      <guid>https://forem.com/thiagomg/using-flutter-with-native-resources-on-apple-silicon-processors-403g</guid>
      <description>&lt;p&gt;If you are building a flutter application for apple processors using Silicon processors (M1+) and dealing with native packages for things such as playing a sound, you maybe encountered this error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error output from CocoaPods:
↳
    /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file --
    ffi_c (LoadError)
        from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /Library/Ruby/Gems/2.6.0/gems/ffi-1.17.0-x86_64-darwin/lib/ffi.rb:5:in `rescue in &amp;lt;top (required)&amp;gt;'
        from /Library/Ruby/Gems/2.6.0/gems/ffi-1.17.0-x86_64-darwin/lib/ffi.rb:2:in `&amp;lt;top (required)&amp;gt;'
        from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
        from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
...

Error: To set up CocoaPods for ARM macOS, run:
  sudo gem uninstall ffi &amp;amp;&amp;amp; sudo gem install ffi -- --enable-libffi-alloc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You probably realised that running &lt;code&gt;sudo gem uninstall ffi &amp;amp;&amp;amp; sudo gem install ffi -- --enable-libffi-alloc&lt;/code&gt; will not work. You are going to get the same error.&lt;/p&gt;

&lt;p&gt;The solution I found was to use cocoapods from brew.&lt;/p&gt;

&lt;p&gt;For that, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;gem uninstall cocoapods
brew &lt;span class="nb"&gt;install &lt;/span&gt;cocoapods
brew &lt;span class="nb"&gt;link &lt;/span&gt;cocoapods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last thing, as I am quite new to flutter and some of the Apple ecosystem, if anyone has a better suggestion, I am all ears.&lt;/p&gt;

&lt;p&gt;Link to the author blog: &lt;a href="https://thiagocafe.com/view/20241220_using_flutter_with_native_resources_on_apple_silicon_processors/" rel="noopener noreferrer"&gt;Using flutter with native resources on apple silicon processors&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>arm</category>
    </item>
    <item>
      <title>sgrep 1.0 released</title>
      <dc:creator>Thiago Massari Guedes</dc:creator>
      <pubDate>Wed, 27 Nov 2024 05:19:56 +0000</pubDate>
      <link>https://forem.com/thiagomg/sgrep-10-released-2on0</link>
      <guid>https://forem.com/thiagomg/sgrep-10-released-2on0</guid>
      <description>&lt;p&gt;Have you ever wanted to see the top line when running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ ps &lt;span class="nt"&gt;-ef&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;bash
  501 56821 56820   0 17Nov24 ttys000    0:00.27 /opt/homebrew/bin/bash &lt;span class="nt"&gt;-l&lt;/span&gt;
  501 95638 56821   0  8:19pm ttys000    0:00.00 &lt;span class="nb"&gt;grep &lt;/span&gt;bash
  501 76214 56820   0 Mon09am ttys002    0:00.44 /opt/homebrew/bin/bash &lt;span class="nt"&gt;-l&lt;/span&gt;
  501 82952 56820   0  7:03pm ttys003    0:00.23 /opt/homebrew/bin/bash &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can with sgrep&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ ps &lt;span class="nt"&gt;-ef&lt;/span&gt; | sgrep &lt;span class="nt"&gt;-t&lt;/span&gt; 1 &lt;span class="nt"&gt;-p&lt;/span&gt; bash
0:   UID   PID  PPID   C STIME   TTY           TIME CMD
642:   501 56821 56820   0 17Nov24 ttys000    0:00.27 /opt/homebrew/bin/bash &lt;span class="nt"&gt;-l&lt;/span&gt;
644:   501 95648 56821   0  8:19pm ttys000    0:00.00 sgrep &lt;span class="nt"&gt;-t&lt;/span&gt; 1 &lt;span class="nt"&gt;-p&lt;/span&gt; bash
645:   501 76214 56820   0 Mon09am ttys002    0:00.44 /opt/homebrew/bin/bash &lt;span class="nt"&gt;-l&lt;/span&gt;
646:   501 82952 56820   0  7:03pm ttys003    0:00.23 /opt/homebrew/bin/bash &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;The main idea of sgrep is to have simple command line options, simple to use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing
&lt;/h3&gt;

&lt;p&gt;Using brew:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew tap thiagomg/texted
brew &lt;span class="nb"&gt;install &lt;/span&gt;thiagomg/texted/simplegrep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or using cargo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;install &lt;/span&gt;sgrep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>linux</category>
      <category>rust</category>
    </item>
    <item>
      <title>Deserialising binary data in Rust</title>
      <dc:creator>Thiago Massari Guedes</dc:creator>
      <pubDate>Thu, 15 Aug 2024 04:25:10 +0000</pubDate>
      <link>https://forem.com/thiagomg/deserialising-binary-data-in-rust-2di4</link>
      <guid>https://forem.com/thiagomg/deserialising-binary-data-in-rust-2di4</guid>
      <description>&lt;p&gt;One common way to deal with serialised data in C++ is to map to a struct, but in Rust with memory ownership and some smart memory optimizations, it is a little more complicated. &lt;/p&gt;

&lt;p&gt;For example, let's say a producer in C++ serialises this message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;book_msg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="kt"&gt;uint8_t&lt;/span&gt; &lt;span class="n"&gt;major_version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// byte 0: message major version  &lt;/span&gt;
    &lt;span class="kt"&gt;uint8_t&lt;/span&gt; &lt;span class="n"&gt;minor_version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// byte 1: message minor version  &lt;/span&gt;
    &lt;span class="kt"&gt;uint8_t&lt;/span&gt; &lt;span class="n"&gt;msg_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;// byte 2: message type  &lt;/span&gt;
    &lt;span class="kt"&gt;uint8_t&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;      &lt;span class="c1"&gt;// byte 3-23: title of the book  &lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// ....&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_msg&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;comm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book_msg&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How can we deserialise that in Rust?&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating the struct to be filled with the data
&lt;/h3&gt;

&lt;p&gt;Rust does not guarantee that the order of the struct arguments is maintained, so we need to use &lt;code&gt;#[repr(C, packed)]&lt;/code&gt; to tell the compiler that the order of the arguments has to be maintained&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[repr(C,&lt;/span&gt; &lt;span class="nd"&gt;packed)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;BookMsg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;major_version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// byte 0: message major version  &lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;minor_version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// byte 1: message minor version  &lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;msg_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;// byte 2: message type  &lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;    &lt;span class="c1"&gt;// byte 3-23: title of the book  &lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Mapping the bytes to a struct
&lt;/h3&gt;

&lt;p&gt;Let's say we received:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 013854546865205369676e206f662074686520466f7572 in hex&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;msg_vec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;comm&lt;/span&gt;&lt;span class="nf"&gt;.recv&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to map this vector to a struct, we need to violate rust safe guarantees as rust cannot verify in compile time that the struct maps to the vector size and data types.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explanation of those 2 lines:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We're casting the pointer from &lt;code&gt;*const u8&lt;/code&gt; to &lt;code&gt;*const Msg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;And then we are accessing it as a value &lt;code&gt;*&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;And finally, getting a reference to this value &lt;code&gt;&amp;amp;&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;msg_bytes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg_vec&lt;/span&gt;&lt;span class="nf"&gt;.as_ptr&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;mapped_msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;BookMsg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg_bytes&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;BookMsg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Beware&lt;/strong&gt;. When accessing parts of the message, it's better to copy the value to an external variable to avoid memory aligning issues.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;major&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mapped_msg&lt;/span&gt;&lt;span class="py"&gt;.major_version&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;minor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mapped_msg&lt;/span&gt;&lt;span class="py"&gt;.minor_version&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;msg_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="py"&gt;.msg_type&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="py"&gt;.title&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Result:&lt;/span&gt;
&lt;span class="c1"&gt;// msg version=1.56, type=84&lt;/span&gt;
&lt;span class="c1"&gt;// msg title="The Sign of the Four"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Use structs with &lt;code&gt;#[repr(C, packed)]&lt;/code&gt; to ensure the layout is preserved&lt;/li&gt;
&lt;li&gt;Use pointers to map to this struct&lt;/li&gt;
&lt;li&gt;Copy the value from the struct to an external variable to avoid memory alignment issues&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Source: &lt;a href="https://thiagocafe.com/view/20240814_deserialising_binary_data_in_rust/" rel="noopener noreferrer"&gt;Deserialising binary data in Rust&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
    </item>
    <item>
      <title>RSS support added to Texted</title>
      <dc:creator>Thiago Massari Guedes</dc:creator>
      <pubDate>Sun, 04 Aug 2024 21:35:59 +0000</pubDate>
      <link>https://forem.com/thiagomg/rss-support-added-to-texted-2j2p</link>
      <guid>https://forem.com/thiagomg/rss-support-added-to-texted-2j2p</guid>
      <description>&lt;p&gt;A Rust developer on twitter posted:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://x.com/andreaskapp/status/1807482647007969730" rel="noopener noreferrer"&gt;"It would be nice to reed updates to your blog in an RSS feed."&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Indeed that is a great idea and I implemented on &lt;a href="https://crates.io/crates/texted" rel="noopener noreferrer"&gt;Texted&lt;/a&gt; 0.3.6!&lt;/p&gt;

&lt;p&gt;Texted is the platform powering both my blogs, &lt;a href="https://thiagocafe.com" rel="noopener noreferrer"&gt;Thiago Café&lt;/a&gt; and &lt;a href="https://blogaro.com.br" rel="noopener noreferrer"&gt;Blogaro!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy reading&lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
    </item>
    <item>
      <title>Texted 0.3.4 released</title>
      <dc:creator>Thiago Massari Guedes</dc:creator>
      <pubDate>Fri, 07 Jun 2024 06:18:34 +0000</pubDate>
      <link>https://forem.com/thiagomg/texted-034-released-2el7</link>
      <guid>https://forem.com/thiagomg/texted-034-released-2el7</guid>
      <description>&lt;p&gt;Texted 0.3.4 released&lt;/p&gt;

&lt;p&gt;Very close to release version 1.0, it comes with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple Markdown support&lt;/li&gt;
&lt;li&gt;Markdown with images&lt;/li&gt;
&lt;li&gt;HTML support with and without images&lt;/li&gt;
&lt;li&gt;texted-tool:

&lt;ul&gt;
&lt;li&gt;creation of posts&lt;/li&gt;
&lt;li&gt;removing special characteres from post url&lt;/li&gt;
&lt;li&gt;bootstrap of a new blog with a simple command&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://gitlab.com/thiagomg/texted/-/blob/main/ChangeLog"&gt;Full Changelog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enjoy and reach out for any questions.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>texted</category>
      <category>blog</category>
    </item>
    <item>
      <title>Quick tip: Type of tokio spawn return</title>
      <dc:creator>Thiago Massari Guedes</dc:creator>
      <pubDate>Tue, 04 Jun 2024 05:07:27 +0000</pubDate>
      <link>https://forem.com/thiagomg/quick-tip-type-of-tokio-spawn-return-42i3</link>
      <guid>https://forem.com/thiagomg/quick-tip-type-of-tokio-spawn-return-42i3</guid>
      <description>&lt;p&gt;When I was implementing the metrics task using tokio, I wanted to save the result &lt;code&gt;JoinHandle&lt;/code&gt; in a struct and I saw the type being displayed by the IDE: &lt;code&gt;JoinHandle&amp;lt;?&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What does it mean?&lt;/p&gt;

&lt;p&gt;When I looked the definition of the function spawn, that's the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;spawn&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;future&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;JoinHandle&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;F&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;  
&lt;span class="k"&gt;where&lt;/span&gt;  
    &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;'static&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
    &lt;span class="nn"&gt;F&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;'static&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the Future trait, &lt;code&gt;F::Output&lt;/code&gt; refers to the return value of the input function.&lt;/p&gt;

&lt;p&gt;Now, the piece of code I have is a long running task. That is the piece of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;receiver_task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Starting metrics receiver"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rx&lt;/span&gt;&lt;span class="nf"&gt;.recv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="py"&gt;.post_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="py"&gt;.origin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
            &lt;span class="nd"&gt;error!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error writing access metric for {}: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="py"&gt;.post_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
            &lt;span class="nd"&gt;debug!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Metric event written for {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="py"&gt;.post_name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
        &lt;span class="p"&gt;}&lt;/span&gt;  
    &lt;span class="p"&gt;}&lt;/span&gt;  
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As this function returns nothing, the type is &lt;a href="https://doc.rust-lang.org/std/primitive.unit.html"&gt;Unit&lt;/a&gt;, hence for this lambda I can declare my struct as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;MetricHandler&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;receiver_task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;JoinHandle&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
    &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now you can do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;receiver_task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="n"&gt;MetricHandler&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;receiver_task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>rust</category>
      <category>tokio</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
