<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Martin Becker</title>
    <description>The latest articles on DEV Community by Martin Becker (@thermatix).</description>
    <link>https://dev.to/thermatix</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%2F26380%2Fdc7afe51-9d5e-4d25-be52-b862a39eed76.png</url>
      <title>DEV Community: Martin Becker</title>
      <link>https://dev.to/thermatix</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thermatix"/>
    <language>en</language>
    <item>
      <title>API and Provider methodology</title>
      <dc:creator>Martin Becker</dc:creator>
      <pubDate>Tue, 29 May 2018 11:55:40 +0000</pubDate>
      <link>https://dev.to/thermatix/api-and-provider-methodology--25j1</link>
      <guid>https://dev.to/thermatix/api-and-provider-methodology--25j1</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;So, One of the biggest issues when designing a library/framework Is when you need to make a call to an external dependency. &lt;/p&gt;

&lt;p&gt;Specifically in the context of this post, when that dependency is no longer usable for any reason, what do you do? Most would then need to implement a new interface for a new dependency, and then as a result potentially make breaking changes to your API to accommodate which isn't good.&lt;/p&gt;

&lt;p&gt;I bring this up because I see all to often libraries that directly call the external dependency in there API methods (I'm guilty of this too -_-), then have to completly change there API when the dependency changes that requires data to be structured differently. &lt;/p&gt;

&lt;p&gt;This then breaks things for many people.&lt;/p&gt;

&lt;p&gt;This is why I advocate separating the API and the external calls into separate classes, it does add complexity and increases the amount of code but the advantage is that when you're external dependency changes, your API doesn't, and nor does it for anyone using you're libraries. &lt;/p&gt;

&lt;p&gt;When I think to do this (ahem) I like to separate the logic into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;API: The API of your library&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provider: The logic that calls your an external dependency&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Formatter: If needed, the logic that handles data formatting between the API and the Provider&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Basic Provider Logic
&lt;/h1&gt;

&lt;p&gt;Now you can do this any way you like, so long as there is a clear separation of concerns. Using ruby as an example, I like to take advantage of the fact you can define &lt;code&gt;def self.[]()&lt;/code&gt; to make my provider API easy to use so I can do somthing like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Module&lt;/span&gt; &lt;span class="no"&gt;Providers&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
        &lt;span class="nb"&gt;attr_writer&lt;/span&gt; &lt;span class="ss"&gt;:listing&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="vi"&gt;@listing&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;       
        &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Provider_Base&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inherited&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;downcase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_sym&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="c1"&gt;# Normally I'd add logic to ensure that only this method can add to&lt;/span&gt;
            &lt;span class="c1"&gt;# `Providers.listing`, but I can't be arsed for this example&lt;/span&gt;
            &lt;span class="no"&gt;Providers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listing&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason I do &lt;code&gt;name = child.class.to_s.downcase.to_sym&lt;/code&gt; in the function declaration is so that if you want you can easily change the way the name is set by doing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Module&lt;/span&gt; &lt;span class="no"&gt;Providers&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OtherProviderBase&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Provider_Base&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inherited&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:some_other_naming_mechaism&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can inherit from &lt;code&gt;OtherProviderBase&lt;/code&gt; instead.&lt;/p&gt;

&lt;h1&gt;
  
  
  Using Your provider
&lt;/h1&gt;

&lt;p&gt;Using the providers in you're api becomes super easy now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;API&lt;/span&gt;

    &lt;span class="no"&gt;PROVIDER_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:provider_name&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method&lt;/span&gt;
        &lt;span class="no"&gt;Providers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;PROVIDER_NAME&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;some_method&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why do it like this? Lets say you build a new dependency provider, you can just change the provider to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;API&lt;/span&gt;

    &lt;span class="no"&gt;PROVIDER_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:other_provider_name&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method&lt;/span&gt;
        &lt;span class="no"&gt;Providers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;PROVIDER_NAME&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;some_method&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;End result is that the API doesn't change and won't break for you of your users.&lt;/p&gt;

&lt;p&gt;And using the above providers example, you can add formatters like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;API&lt;/span&gt;
    &lt;span class="no"&gt;PROVIDER_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:provider_name&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method&lt;/span&gt;
        &lt;span class="no"&gt;Formatters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;PROVIDER_NAME&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;some_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="no"&gt;Providers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;PROVIDER_NAME&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;some_method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can even go further and do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;API&lt;/span&gt;

    &lt;span class="no"&gt;PROVIDER_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:provider_name&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;some_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:some_method&lt;/span&gt;
        &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Providers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;PROVIDER_NAME&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Formatters&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;PROVIDER_NAME&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="no"&gt;Formatters&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;PROVIDER_NAME&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;method&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="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Provider Piplines
&lt;/h1&gt;

&lt;p&gt;You could even provide a mechanism (where appropriate of course) to automatically pipeline, like this maybe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Pipelines&lt;/span&gt;
    &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:listing&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;pipline_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pipes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@listing&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pipes&lt;/span&gt;
        &lt;span class="n"&gt;define_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
            &lt;span class="n"&gt;run_pipline_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extended&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Instance_Methods&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Instance_Methods&lt;/span&gt;
       &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run_pipline_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
           &lt;span class="no"&gt;Pipelines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listing&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;custom_action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
              &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;PROVIDER_NAME&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;custom_action&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
           &lt;span class="k"&gt;end&lt;/span&gt;
       &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;API&lt;/span&gt;
    &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;Pipeline&lt;/span&gt;

    &lt;span class="no"&gt;PROVIDER_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:provider_name&lt;/span&gt;

    &lt;span class="n"&gt;pipline_for&lt;/span&gt; &lt;span class="ss"&gt;:action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Formatters&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Providers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:get_remote_data&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="no"&gt;Formatters&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Output&lt;/span&gt;
    &lt;span class="n"&gt;pipline_for&lt;/span&gt; &lt;span class="ss"&gt;:other_action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Formatters&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Providers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Processors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:differing_name&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Formatters&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:custom_output&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;blockquote&gt;
&lt;p&gt;Sorry, this probably out of scope for this post but couldn't help myself when I saw somthing interesting to code. Also I'm not sure if &lt;code&gt;PROVIDER_NAME&lt;/code&gt; will be picked up in the local context of the &lt;code&gt;API&lt;/code&gt; class when &lt;code&gt;Pipeline&lt;/code&gt; is included so you might need to code a mechanism for setting and retrieval that does but you get the idea. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  conclusion
&lt;/h1&gt;

&lt;p&gt;By separating your external dependency into it's logic that is then called by your API, you can then keep your API constant between versions and then the only difference between versions becomes the dependencies, without any breaking changes between them.&lt;/p&gt;

&lt;p&gt;p.s. I completly admit to not having checked or tested any of this code as it was just examples to get the ball rolling.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>methodology</category>
    </item>
    <item>
      <title>Explain RPC like I'm Five</title>
      <dc:creator>Martin Becker</dc:creator>
      <pubDate>Thu, 17 May 2018 09:14:43 +0000</pubDate>
      <link>https://dev.to/thermatix/explain-rpc-like-im-five-5f7j</link>
      <guid>https://dev.to/thermatix/explain-rpc-like-im-five-5f7j</guid>
      <description>

&lt;p&gt;I'm having a little trouble understanding RPC, especially compared to say Rest API's or using protobufs to send and receive data, so please explain RPC like I'm Five?&lt;/p&gt;


</description>
      <category>explainlikeimfive</category>
    </item>
    <item>
      <title>Building My own website</title>
      <dc:creator>Martin Becker</dc:creator>
      <pubDate>Wed, 16 May 2018 21:39:54 +0000</pubDate>
      <link>https://dev.to/thermatix/building-my-own-website-5af0</link>
      <guid>https://dev.to/thermatix/building-my-own-website-5af0</guid>
      <description>

&lt;h1&gt;Introduction&lt;/h1&gt;

&lt;p&gt;So as far as I've seen most developers have there own website but for me, sadly I'm yet to do this so I've decided It's time to embark on the time honoured tradition[&lt;a href="https://dev.to/thermatix/building-my-own-website-5af0#author_note_1"&gt;1&lt;/a&gt;] of a dev building there own personal site!&lt;/p&gt;

&lt;p&gt;But I thought I'd make it interesting by over-engineering it on purpose. &lt;/p&gt;

&lt;p&gt;My reasoning is several:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I can put to practice the knowledge I've accumulated on systems architecture&lt;/li&gt;
&lt;li&gt;I can build using interesting technology I've been wanting to try&lt;/li&gt;
&lt;li&gt;I can learn how to use new things&lt;/li&gt;
&lt;li&gt;Fun!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, I've decided to plan out what I'm thinking of doing here, any discussion or ideas would be and are welcome!&lt;/p&gt;

&lt;p&gt;This document is also to act as a kind of repository of useful links with context that are related to the things I've chosen.&lt;/p&gt;

&lt;h2&gt;Checklists&lt;/h2&gt;

&lt;h3&gt;Selections&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Basic Architecture

&lt;ul&gt;
&lt;li&gt;[ ] &lt;a href="https://dev.to/thermatix/building-my-own-website-5af0#message_que"&gt;Message Queue&lt;/a&gt;: Kafka|RabbitMQ|AWS SQS&lt;/li&gt;
&lt;li&gt;[√] &lt;a href="https://dev.to/thermatix/building-my-own-website-5af0#message_format"&gt;Message format&lt;/a&gt;: Message Pack&lt;/li&gt;
&lt;li&gt;[ ] &lt;a href="https://dev.to/thermatix/building-my-own-website-5af0#routing"&gt;Routing&lt;/a&gt;: Nuster|Nginx&lt;/li&gt;
&lt;li&gt;[√] &lt;a href="https://dev.to/thermatix/building-my-own-website-5af0#deployment"&gt;Deployment&lt;/a&gt;: Docker &amp;amp; Chef?&lt;/li&gt;
&lt;li&gt;[√] &lt;a href="https://dev.to/thermatix/building-my-own-website-5af0#ci"&gt;CI&lt;/a&gt;: Travis&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;br&gt;
&lt;li&gt;Front end

&lt;ul&gt;
&lt;li&gt;[√] &lt;a href="https://dev.to/thermatix/building-my-own-website-5af0#view_framework"&gt;View framework&lt;/a&gt;: Marko&lt;/li&gt;
&lt;li&gt;[√] &lt;a href="https://dev.to/thermatix/building-my-own-website-5af0#state"&gt;State&lt;/a&gt;: Vuex&lt;/li&gt;
&lt;li&gt;[√] &lt;a href="https://dev.to/thermatix/building-my-own-website-5af0#visual"&gt;Visual&lt;/a&gt;: Materializecss&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;br&gt;
&lt;li&gt;Back end

&lt;ul&gt;
&lt;li&gt;[√] &lt;a href="https://dev.to/thermatix/building-my-own-website-5af0#ruby"&gt;Ruby&lt;/a&gt;: Rack + Custom Middleware&lt;/li&gt;
&lt;li&gt;[√] &lt;a href="https://dev.to/thermatix/building-my-own-website-5af0#rust"&gt;Rust&lt;/a&gt;: tokio-serde-msgpack&lt;/li&gt;
&lt;li&gt;[√] &lt;a href="https://dev.to/thermatix/building-my-own-website-5af0#api"&gt;API&lt;/a&gt;: Roda&lt;/li&gt;
&lt;/ul&gt;


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

&lt;h3&gt;Features I may add&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;a href="https://dev.to/thermatix/building-my-own-website-5af0#dev_to_feed"&gt;dev.to post feed&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Services&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Front end (I'll Add to this as I think of more services)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Front End app distro&lt;/li&gt;
&lt;li&gt;[ ] Routing/caching (Nuster/Nginx)&lt;/li&gt;
&lt;li&gt;[ ] Front end App distro-service (maybe Node but what ever works best)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;br&gt;
&lt;li&gt;

&lt;p&gt;Front Facing Back-end (I'll Add to this as I think of more services)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API (I'll add to this as I add API's)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;br&gt;
&lt;li&gt;

&lt;p&gt;Rear Facing Back-end (I'll Add to this as I think of more services)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Message Queue (maybe, maybe not)&lt;/li&gt;
&lt;/ul&gt;


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

&lt;h3&gt;Usefull links&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Docker

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/kevin-smets/b91a34cea662d0c523968472a81788f7"&gt;Kubernetes on Macos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hackernoon.com/getting-started-with-microservices-and-kubernetes-76354312b556"&gt;Getting started with micro-services and Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


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

&lt;h1&gt;The Plan&lt;/h1&gt;

&lt;p&gt;My idea for my plan is to list things that I think of and what I can do for that item the idea is to fill the list, some of them I'm not sure about I'll put two or more items, I would appreciate some input on them!&lt;/p&gt;

&lt;p&gt;I don't know if I'll ever get around to completly building this, but at least if I have a plan I'll have something to work towards.&lt;/p&gt;

&lt;p&gt;Lastly, I might put somthing in the plan but this is also for fun so If somthing becomes to annoying or beyond the scope of fun I'll probably not do it. &lt;/p&gt;

&lt;h2&gt;Basic Architecture:&lt;/h2&gt;

&lt;h3&gt;Host&lt;/h3&gt;

&lt;p&gt;I've decided to go with AWS, whilst it might be fairly close to the metal it will allow me to get to the nitty gritty&lt;/p&gt;

&lt;h3&gt;Code&lt;/h3&gt;

&lt;p&gt;I've decided to go with ruby and rust on the backend, since I'm building with micro-services I can build small services in which ever language I like, or build in ruby first to get somthing running then migrate to rust or hybridise and build with ruby and use FFI for rust. &lt;/p&gt;

&lt;h3&gt;Infastructure&lt;/h3&gt;

&lt;p&gt;I decided to go with micro-services becuase it's always somthing I wanted to try doing to that end I need to some infrastructure to go with it. &lt;/p&gt;

&lt;p&gt;if I decided I can't be arsed with this I'll just go with a standard monolith and then add micro-services on the side or start as a monolith and then migrate to to micro-services instead.&lt;/p&gt;

&lt;div id="message_que"&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;h4&gt;Message-queue&lt;/h4&gt;
I was thinking about going with &lt;a href="https://kafka.apache.org/"&gt;kafka&lt;/a&gt; or &lt;a href="https://www.rabbitmq.com/"&gt;RabbitMQ&lt;/a&gt; but In thinking about it, I've decided to go with &lt;a href="https://aws.amazon.com/sqs/"&gt;SQS&lt;/a&gt;. As much fun and as interesting as it would be to set up, I really don't need somthing with that much throughput as Kafka or as heavy as RabbitMQ and SQS is supported by Rust, Ruby and Javascript.
&lt;div id="message_format"&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h4&gt;Message-format&lt;/h4&gt;
I've decided to go with &lt;a href="https://msgpack.org/index.html"&gt;message-pack&lt;/a&gt;, somthing I've had my eye on and should interesting to implement and use across Ruby, Rust and JavaScript(front end).
&lt;div id="routing"&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h4&gt;Routing&lt;/h4&gt;
I've decided to go with trying &lt;a href="https://dev.to/nuster/nuster---a-web-caching-proxy-server-based-on-haproxy-40k2"&gt;Nuster&lt;/a&gt; as it looks interesting and I've never used it before. But if I can't get it to work as I want I'll go with &lt;a href="https://www.nginx.com/"&gt;Nginx&lt;/a&gt; as I've used it in the past
&lt;div id="deployment"&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h4&gt;Deployment&lt;/h4&gt;
I've decided to go with &lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt; as I've never used it before so It will be interesting to implement, I'm not sure if I'll need somthing like Chef for deployments though or if I should combine them as i'm a little confused if I need both of them or not.
&lt;div id="ci"&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h4&gt;CI&lt;/h4&gt;
I've decided to go with &lt;a href="https://travis-ci.org/"&gt;Travis&lt;/a&gt;, again becuase I've never used it and it's free.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think that's about it for Infrastructure beyond using S3 for assets and stuff, Postgresql (or amazon aura) as my DB &lt;/p&gt;

&lt;h2&gt;Website structure:&lt;/h2&gt;

&lt;h3&gt;Front end&lt;/h3&gt;

&lt;div id="view_framework"&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;h4&gt;View framework&lt;/h4&gt;
I've decided to go with &lt;a href="https://markojs.com/"&gt;Marko&lt;/a&gt; becuase Marko's &lt;a href="https://gist.github.com/patrick-steele-idem/cd291a2c21ba7ea2a7e12a06467249e5"&gt;Syntax&lt;/a&gt; is just so nice and is highly &lt;a href="https://hackernoon.com/server-side-rendering-shootout-with-marko-preact-rax-react-and-vue-25e1ae17800f"&gt;performant&lt;/a&gt; and honestly Marko just looks more interesting. 
&lt;div id="state"&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h4&gt;State&lt;/h4&gt;
&lt;a href="https://vuex.vuejs.org/en/intro.html"&gt;Vuex&lt;/a&gt;, no competition, it just looks easier to use then redux (and 
honestly, mutations is a lot easier to understand then reducers in terms of understanding it &amp;amp; context) 
&lt;div id="visual"&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h4&gt;Visual&lt;/h4&gt;
&lt;a href="http://materializecss.com/"&gt;Materializecss&lt;/a&gt;, honestly this is my second choice, my first is fluent design but the only thing I can find is a &lt;a href="https://www.react-uwp.com/"&gt;React component framework&lt;/a&gt; which whilst nice looking (I would say sexy) Is still React when I want to use Vue or Marko. Materializecss is still nice and if I wanted to I could do some acrylic effects to add some to it. As framework however I do like it, way more then bootstrap.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Back end&lt;/h3&gt;

&lt;div id="ruby"&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;h4&gt;Ruby&lt;/h4&gt;
&lt;a href="https://rack.github.io/"&gt;Rack&lt;/a&gt; + Custom Rack Middleware: In most cases be using Rack to mount apps with some custom built middleware. Since I intend to Build this as a front end JS app with an API backend, if someone knows how to distribute the base HTML + assets without needing somthing like Sinatra then please point in the direction!
&lt;div id="rust"&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h4&gt;Rust&lt;/h4&gt;
&lt;a href="https://github.com/tene/tokio-serde-msgpack"&gt;tokio-serde-msgpack&lt;/a&gt;
&lt;div id="api"&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h4&gt;API&lt;/h4&gt;
I've decided to use &lt;a href="https://github.com/jeremyevans/roda"&gt;Roda&lt;/a&gt; &lt;a href="http://blog.davydovanton.com/2016/05/20/develop-api-with-roda/"&gt;for&lt;/a&gt; &lt;a href="https://github.com/beno/roda-rest_api"&gt;API&lt;/a&gt; &lt;a href="http://gafur.me/2017/10/30/building-api-with-roda-and-sequel.html"&gt;stuff&lt;/a&gt; as it looks interesting, I'll then use a messaging library to pass messages to the message queue and then any MS will then pick up the appropriate messages, send a response and then the API service will respond. To be honest though I'm not sure, as I've said I'm doing this as learning experience as my knowledge is currently almost zero, once I get a better understanding I'll change this section.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Features&lt;/h2&gt;

&lt;div id="dev_to_feed"&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt; &lt;h4&gt; dev.to post feed &lt;/h4&gt;
Instead of building a blog I'd much rather just post dev.to and have links to my posts appear on my site. To that end I can use the dev.to articles api &lt;code&gt;dev.to/api/articles?username=thermatix&lt;/code&gt;, there is an RSS feed but I'd much rather just use the API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For now This is all I have, I'll add more sections as I think of them or decide  they should be added, once my plan is complete I'll create a list of things I'm going to build as a separate document, publish it and then update it with any appropriate links and info.&lt;/p&gt;

&lt;h3&gt;Authors Notes&lt;/h3&gt;

&lt;div id="author_note_1"&gt;&lt;/div&gt;

&lt;p&gt;[1]: building a dev site is probably not a time-honoured tradition but I thought it fit.&lt;/p&gt;


</description>
      <category>personalsite</category>
      <category>rust</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Switched to Alacritty</title>
      <dc:creator>Martin Becker</dc:creator>
      <pubDate>Tue, 01 May 2018 15:16:43 +0000</pubDate>
      <link>https://dev.to/thermatix/switched-to-alacritty-2jfh</link>
      <guid>https://dev.to/thermatix/switched-to-alacritty-2jfh</guid>
      <description>&lt;p&gt;I just switched to using Alacritty (as in about 40 mins ago, give or take). It's a fair bit more bare bones then the ITerm2 I was using but to be completly honest I never used any of the extra features provided by it so I'm not missing anything. &lt;/p&gt;

&lt;p&gt;It's a lot faster than Iterm2 by a lot I'm also finding that Nvim has sped up a lot and by far the best feature is that it's solved one the biggest bugbears I've ever had about Iterm2 (and Apples Term). I use Powerline fonts but one the biggest issues is that ITerm2 never rendered them properly as a result the tips of the powerline characters stuck up and as a result made everything just a little bit ugly. That problem is non-existent on Alacritty (at least for me)&lt;/p&gt;

&lt;p&gt;AS for negatives there are a few. To use it as an &lt;code&gt;.app&lt;/code&gt; you have to clone the repo and then build it, not a big issue but it took a while. &lt;/p&gt;

&lt;p&gt;I did have issues getting Alacritty to find the font I wanted. I told it to look for a font called &lt;code&gt;Knack Regular Nerd Font Complete&lt;/code&gt; but it kept saying it didn't exist. I posted an issue and someone said they tried &lt;code&gt;Knack Nerd Font&lt;/code&gt; so I tried that and it worked.&lt;/p&gt;

&lt;p&gt;Finally there is a bug I get with tmux, where the last character of the status line is moved to the beginning of the next line. For some people it would be a deal breaker but for me I can live with it as it appears next to buffer tab line (airline) on neovim so I don't notice it plus I can live with that over misaligned powerline characters so long as I set the last line of the tmux status line to &lt;code&gt;|&lt;/code&gt;. I've added an &lt;a href="https://github.com/jwilm/alacritty/issues/1288" rel="noopener noreferrer"&gt;issue on Github&lt;/a&gt; so hopefully it gets fixed soon.&lt;/p&gt;

&lt;p&gt;Any way, I'm really liking it and can't wait for it to get even better.&lt;/p&gt;

</description>
      <category>terminal</category>
      <category>alacritty</category>
    </item>
    <item>
      <title>Building My first Rust Project: Wercker Build Status</title>
      <dc:creator>Martin Becker</dc:creator>
      <pubDate>Wed, 04 Apr 2018 17:39:37 +0000</pubDate>
      <link>https://dev.to/thermatix/building-my-first-rust-project-wercker-build-status-3fkl</link>
      <guid>https://dev.to/thermatix/building-my-first-rust-project-wercker-build-status-3fkl</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;warning This is my first ever techy blog post so I hope you'll forgive any errors or badly written sections.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;My main language of choice is ruby, I like it's ease of use, it's simplicity and expressiveness and it's malability makes it a dream to use, It is however Slow, lacks clear typing and even subtle bugs can crop up if you aren't aware of the fact that ruby is both pass by value and reference as you can see here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'hello '&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s1"&gt;'world'&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'hello world'&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Whilst all of it's pro's make rapidly building something easy it can make it difficult to maintain over long term.&lt;/p&gt;

&lt;p&gt;Enter Rust!&lt;/p&gt;

&lt;p&gt;As far as I'm concerned Rust is the perfect partner to ruby, it's fast where ruby is slow, it's typed where ruby isn't and you never need to worry about undefined behavior or subtle bugs due to its nature.&lt;/p&gt;

&lt;p&gt;To that end I decided on learning rust to act as a foil to ruby. Learning rust has been hard but worth it I feel.&lt;/p&gt;

&lt;h1&gt;
  
  
  The tool - &lt;a href="https://github.com/thermatix/wercker_build_status" rel="noopener noreferrer"&gt;Werker Build Status&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;This tool exists because at my job we use Oracle's Wercker (I keep calling it wrecker) to handle Continues Intergration but I have a tendency not to pay attention to when a build is failing so I thought I'd build a tool to display the status of my last build in the Tmux status line.&lt;/p&gt;

&lt;p&gt;Before I started working on this tool I'd always felt lost when working with the language, I can safely say that this is the first time I'd worked with rust and felt like I knew what I was doing (more or less). &lt;/p&gt;

&lt;p&gt;Originally I was going to build a bash script around the Wercker CLI tool, but then it occurred to me that it's not a large project and its scope is small, wouldn't that be perfect for my first project with Rust? So I did, and I started with planning.&lt;/p&gt;

&lt;h1&gt;
  
  
  Planning
&lt;/h1&gt;

&lt;p&gt;I realised that my tool could be broken down into steps that I could then use to work out what crates I might use to make to make it easier (something I admit I don't normally do).&lt;/p&gt;

&lt;p&gt;1) Loading user config - &lt;a href="https://crates.io/crates/config" rel="noopener noreferrer"&gt;config&lt;/a&gt;&lt;br&gt;
2) Getting the list of runs - &lt;a href="https://crates.io/crates/curl" rel="noopener noreferrer"&gt;curl&lt;/a&gt;&lt;br&gt;
3) Deserializing the json - &lt;a href="https://crates.io/crates/serde_json" rel="noopener noreferrer"&gt;serde_json&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I admit that normally I'd just jump into ruby and start hammering code out however due to the nature of rust and the fact I don't know it that well I thought it would be a good idea to plan it out and it ended up working in my favour.&lt;/p&gt;
&lt;h1&gt;
  
  
  Loading the User Config
&lt;/h1&gt;

&lt;p&gt;I honestly found this to be the easiest of all the steps as the documentation was easy to follow, for me I simply added a single function to take care of loading the config:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;collections&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&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;Config&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// create config object&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;config_rs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// check if config_file was supplied, if it was then load it    &lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;config_file&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="nf"&gt;.merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;config_rs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config_file&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;//check for and add env variables&lt;/span&gt;
    &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="nf"&gt;.merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;config_rs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_prefix&lt;/span&gt;&lt;span class="p"&gt;(::&lt;/span&gt;&lt;span class="n"&gt;CONFIG_PREFIX&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="py"&gt;.try_into&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Initially  I was checking for each key I needed with an if statement to check if a key existed but in the end I found that this to be the dry-ist way to do it but still remaining flexible:&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;// check if config options exists&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"pipeline_id"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.position&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="nf"&gt;.contains_key&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;key&lt;/span&gt;&lt;span class="nf"&gt;.to_string&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="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;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;"No `{}` detected in config or env ({}_{}) variables"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;[&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;CONFIG_PREFIX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.to_uppercase&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
    &lt;span class="nb"&gt;None&lt;/span&gt;    &lt;span class="k"&gt;=&amp;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;h1&gt;
  
  
  Getting the list of runs
&lt;/h1&gt;

&lt;p&gt;This was were things started getting tricky, Setting up the Curl client was fairly straightforward:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;set_up&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;String&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;Easy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;curl&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;easy&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;easy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Easy&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// add authorisation header to curl client&lt;/span&gt;
    &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="nf"&gt;.append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Authorization: Bearer {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;easy&lt;/span&gt;&lt;span class="nf"&gt;.http_headers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;easy&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;I created a function to handle doing get requests:&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;fn&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;curl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Easy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;curl&lt;/span&gt;&lt;span class="nf"&gt;.url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// add mechanism to transfer data recived data into a vec&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;transfer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curl&lt;/span&gt;&lt;span class="nf"&gt;.transfer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;transfer&lt;/span&gt;&lt;span class="nf"&gt;.write_function&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;new_data&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="nf"&gt;.extend_from_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_data&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;transfer&lt;/span&gt;&lt;span class="nf"&gt;.perform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Return Data!&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;However this is where I encountered my first hiccup, where I was expecting a JSON string I was getting a &lt;code&gt;Vec[u8]&lt;/code&gt; it puzzled me for a bit but then I realised that curl was outputting raw bytes, a bit of digging and the answer was to change the last line to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// convert byte result into utf_8 string&lt;/span&gt;
&lt;span class="nn"&gt;str&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_utf8&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;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I was getting a JSON string!&lt;/p&gt;

&lt;h1&gt;
  
  
  Deserializing the json
&lt;/h1&gt;

&lt;p&gt;At first I was content to just filter the build runs by author and then grab the first deserialized object:&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="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set_up_client&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;settings&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"token"&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;runs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;get_runs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;client&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;settings&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"author"&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;settings&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"pipeline_id"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;runs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;FIRST&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However due to what appears to be a bug on the Wercker API this wasn't possible. the bug was that no matter what I set as the author (a username, random letters) it would always send back the last builds of the same incorrect user.&lt;/p&gt;

&lt;p&gt;This means means I have to instead grab the last 20 runs and manually find the first with a matching username, to do that I had to create structs to represent the data I wanted:&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;type&lt;/span&gt; &lt;span class="n"&gt;Runs&lt;/span&gt; &lt;span class="o"&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="n"&gt;Run&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;// only define the structs for the data I want to pull out&lt;/span&gt;
&lt;span class="nd"&gt;#[derive(Debug,Serialize,&lt;/span&gt; &lt;span class="nd"&gt;Deserialize)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Run&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;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&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;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&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;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Debug,Serialize,&lt;/span&gt; &lt;span class="nd"&gt;Deserialize)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;User&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;meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Debug,Serialize,&lt;/span&gt; &lt;span class="nd"&gt;Deserialize)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Meta&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;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then deserialize to my struct:&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;runs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Runs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;client&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_runs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;client&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;settings&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"pipeline_id"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I honestly didn't want to have to do this as the basic deserialisation was fine for my needs as I wasn't intending to store the results however &lt;code&gt;Serde&lt;/code&gt; wouldn't co-operate quite so nicely, I tried doing this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;runs&lt;/span&gt;&lt;span class="nf"&gt;.as_array&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.find&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However I found that serde only returns a &lt;code&gt;Vec[String]&lt;/code&gt; with a single element containing the entire JSON string, so manually creating the deserialized data was the only way. &lt;/p&gt;

&lt;p&gt;Another issue I found was that following the serde documentation gave me a puzzling result:&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;runs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;client&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_runs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;client&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;settings&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"pipeline_id"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It didn't like me using &lt;code&gt;?&lt;/code&gt; operator, it turns out I'd completely missed the fact you can't use it nor &lt;code&gt;try!&lt;/code&gt; in main because they both return and you can't return in main, changing &lt;code&gt;?&lt;/code&gt; to &lt;code&gt;unwrap()&lt;/code&gt; solved the issue.&lt;/p&gt;

&lt;h1&gt;
  
  
  Displaying the result
&lt;/h1&gt;

&lt;p&gt;Lastly I iterate through the &lt;code&gt;Vec[Runs]&lt;/code&gt; and display the first to match the username:&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;match&lt;/span&gt; &lt;span class="n"&gt;runs&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;|&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;run&lt;/span&gt;&lt;span class="py"&gt;.user.meta.username&lt;/span&gt;&lt;span class="nf"&gt;.to_lowercase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.to_lowercase&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="c1"&gt;// print out status and result&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;run&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="nf"&gt;.contains_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tmux"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"tmux"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="py"&gt;.result&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s"&gt;"failed"&lt;/span&gt;    &lt;span class="k"&gt;=&amp;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;"##[fg=red,bold]{}"&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;run&lt;/span&gt;&lt;span class="py"&gt;.result&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="s"&gt;"passed"&lt;/span&gt;    &lt;span class="k"&gt;=&amp;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;"#[fg=green,bold,bright]{}"&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;run&lt;/span&gt;&lt;span class="py"&gt;.result&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="s"&gt;"aborted"&lt;/span&gt;    &lt;span class="k"&gt;=&amp;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;"#[fg=yellow,bold,bright]{}"&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;run&lt;/span&gt;&lt;span class="py"&gt;.result&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="n"&gt;_&lt;/span&gt;           &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"#[fg=blue,bright]{}"&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;run&lt;/span&gt;&lt;span class="py"&gt;.status&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="py"&gt;.result&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s"&gt;"failed"&lt;/span&gt;    &lt;span class="k"&gt;=&amp;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;"{}"&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;run&lt;/span&gt;&lt;span class="py"&gt;.result&lt;/span&gt;&lt;span class="nf"&gt;.red&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
                &lt;span class="s"&gt;"passed"&lt;/span&gt;    &lt;span class="k"&gt;=&amp;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;"{}"&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;run&lt;/span&gt;&lt;span class="py"&gt;.result&lt;/span&gt;&lt;span class="nf"&gt;.green&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
                &lt;span class="s"&gt;"aborted"&lt;/span&gt;    &lt;span class="k"&gt;=&amp;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;"{}"&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;run&lt;/span&gt;&lt;span class="py"&gt;.result&lt;/span&gt;&lt;span class="nf"&gt;.yellow&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
                &lt;span class="n"&gt;_&lt;/span&gt;           &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt;  &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&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;run&lt;/span&gt;&lt;span class="py"&gt;.status&lt;/span&gt;&lt;span class="nf"&gt;.blue&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;span class="nb"&gt;None&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;print!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"None Found"&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;h1&gt;
  
  
  conclusion
&lt;/h1&gt;

&lt;p&gt;Learning Rust was worth it and this tool I built though basic shows me that I can build things with this language. A someone that has a tendency to forget things and not notice when things are slightly off, rust helps a lot in this regard as it just won't compile when things aren't right so it's nice that if it compile it will pretty much work (barring any bugs of course).&lt;/p&gt;

&lt;p&gt;There are a few things I did not cover in this as the point isn't to show the program in its entirety, if you want to see it all you can look at the repo the tool is stored at  which can be found &lt;a href="https://github.com/thermatix/wercker_build_status" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'm honestly glad I took the time to learn rust and I feel it will be of help in my future endeavours. &lt;/p&gt;

&lt;p&gt;Thank you for taking the time to read this retrospective I hope it was in any way informative to you.&lt;/p&gt;

</description>
      <category>rust</category>
    </item>
    <item>
      <title>Devs, why do you use terminal tabs over tmux windows?</title>
      <dc:creator>Martin Becker</dc:creator>
      <pubDate>Tue, 06 Mar 2018 11:46:58 +0000</pubDate>
      <link>https://dev.to/thermatix/devs-why-do-you-use-terminal-tabs-over-tmux-windows--51hb</link>
      <guid>https://dev.to/thermatix/devs-why-do-you-use-terminal-tabs-over-tmux-windows--51hb</guid>
      <description>&lt;p&gt;Just a quick thought, I've noticed a lot of developers seem to use terminal tabs, even when using tmux which has windows, so I'm curious, why use terminal tabs over tmux windows?&lt;/p&gt;

&lt;p&gt;One thing to point out is that when you use tabs, it steals a bit of screen real-estate which can be used to display more of the terminal. By using tmux windows it displays the windows open in the tmux status line instead of a seperate line.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>terminal</category>
    </item>
    <item>
      <title>Hi, I'm Martin Becker</title>
      <dc:creator>Martin Becker</dc:creator>
      <pubDate>Mon, 17 Jul 2017 20:24:15 +0000</pubDate>
      <link>https://dev.to/thermatix/hi-im-martin-becker</link>
      <guid>https://dev.to/thermatix/hi-im-martin-becker</guid>
      <description>&lt;p&gt;I have been coding on and off for 4 years.&lt;/p&gt;

&lt;p&gt;You can find me on GitHub as &lt;a href="https://github.com/Thermatix" rel="noopener noreferrer"&gt;Thermatix&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I live in Farnborough (just moved here last friday(14th of july, 2017).&lt;/p&gt;

&lt;p&gt;I work for formulate digital.&lt;/p&gt;

&lt;p&gt;I mostly program in these languages: Ruby, javascript.&lt;/p&gt;

&lt;p&gt;I am currently learning more about Rust.&lt;/p&gt;

&lt;p&gt;Nice to meet you.&lt;/p&gt;

</description>
      <category>introduction</category>
    </item>
  </channel>
</rss>
