<?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: Allwell</title>
    <description>The latest articles on DEV Community by Allwell (@allwelldotdev).</description>
    <link>https://dev.to/allwelldotdev</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%2F1042852%2Fc4c360f3-f786-465e-8b2b-fe878a0b4b43.JPG</url>
      <title>DEV Community: Allwell</title>
      <link>https://dev.to/allwelldotdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/allwelldotdev"/>
    <language>en</language>
    <item>
      <title>How To Make A Custom Type Iterable In Rust.</title>
      <dc:creator>Allwell</dc:creator>
      <pubDate>Tue, 11 Nov 2025 20:45:01 +0000</pubDate>
      <link>https://dev.to/allwelldotdev/how-to-make-a-custom-type-iterable-in-rust-c0i</link>
      <guid>https://dev.to/allwelldotdev/how-to-make-a-custom-type-iterable-in-rust-c0i</guid>
      <description>&lt;p&gt;Learn how to make your custom type implement the &lt;code&gt;IntoIterator&lt;/code&gt;, &lt;code&gt;Iterator&lt;/code&gt;, and &lt;code&gt;FromIterator&lt;/code&gt; trait. Understand how to add the &lt;code&gt;into_iter&lt;/code&gt;, &lt;code&gt;iter&lt;/code&gt;, and &lt;code&gt;iter_mut&lt;/code&gt; methods to your custom type.&lt;/p&gt;




&lt;p&gt;In my former article, &lt;a href="https://dev.to/allwelldotdev/how-to-build-a-heapless-vector-using-maybeuninit-for-better-performance-ojo"&gt;How to build a Heapless Vector using &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; for Better Performance&lt;/a&gt;, I taught how to build a heapless vector data structure to enable a &lt;code&gt;Vec&lt;/code&gt;-like data structure without heap allocation for use in embedded systems where heap allocation is unlikely. The heapless vector &lt;code&gt;ArrayVec&lt;/code&gt; is a wrapper type over a fixed-sized array that utilizes uninitialized, stack, and static memory to mimic the functionality of a variably-sized &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; with methods like &lt;code&gt;try_push()&lt;/code&gt;, &lt;code&gt;get()&lt;/code&gt;, and &lt;code&gt;as_slice()&lt;/code&gt; to convert the type into a slice with pointer references to its array values.&lt;/p&gt;

&lt;p&gt;In this article, we'll learn how to iterate through &lt;code&gt;ArrayVec&lt;/code&gt;. As a custom type, we will implement iterator traits on &lt;code&gt;ArrayVec&lt;/code&gt; that make it iterable (e.g. usable in a &lt;code&gt;for&lt;/code&gt; loop).&lt;/p&gt;

&lt;p&gt;These are the traits we'll learn about and implement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;IntoIterator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Iterator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FromIterator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Extend&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's describe what these traits mean and do in Rust and why they're important in making a type iterable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Iterator Traits
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;IntoIterator&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;IntoIterator&lt;/code&gt; trait is the foundation for making your custom type (in our case, &lt;code&gt;ArrayVec&lt;/code&gt;) iterable in &lt;code&gt;for&lt;/code&gt; loops (e.g., &lt;code&gt;for item in &amp;amp;vec { ... }&lt;/code&gt;) and compatible with iterator methods like &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, etc. It defines how to convert your type &lt;em&gt;into&lt;/em&gt; an iterator, with an associated &lt;code&gt;Item&lt;/code&gt; type (such as &lt;code&gt;T&lt;/code&gt; for by-value, &lt;code&gt;&amp;amp;T&lt;/code&gt; for by-reference, or &lt;code&gt;&amp;amp;mut T&lt;/code&gt; for by-mutable-reference) and &lt;code&gt;IntoIter&lt;/code&gt; type (the actual iterator type of your custom type, also known as &lt;em&gt;concrete iterator&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Let's elaborate a little further on the meaning of the &lt;code&gt;IntoIterator::IntoIter&lt;/code&gt; associated type and the &lt;em&gt;concrete iterator&lt;/em&gt; it points to: To make &lt;code&gt;ArrayVec&lt;/code&gt; iterable, we implement &lt;code&gt;IntoIterator&lt;/code&gt; on &lt;code&gt;ArrayVec&lt;/code&gt; and set the &lt;code&gt;IntoIter&lt;/code&gt; associated type to something like &lt;code&gt;ArrayVecIntoIter&lt;/code&gt;. Why? Because when we call &lt;code&gt;into_iter()&lt;/code&gt; on &lt;code&gt;ArrayVec&lt;/code&gt; it returns, &lt;code&gt;ArrayVecIntoIter&lt;/code&gt;, an iterator (i.e. a type that implements the &lt;code&gt;Iterator&lt;/code&gt; trait). How do we make &lt;code&gt;ArrayVecIntoIter&lt;/code&gt; an iterator? By creating a new type, &lt;code&gt;ArrayVecIntoIter&lt;/code&gt;, that mirrors iterable and utility fields on &lt;code&gt;ArrayVec&lt;/code&gt; and implements &lt;code&gt;Iterator&lt;/code&gt;. So we make &lt;code&gt;ArrayVecIntoIter&lt;/code&gt; an iterator by implementing the required &lt;code&gt;next&lt;/code&gt; method on it, along with other provided methods if we need them. That way, when you call &lt;code&gt;into_iter()&lt;/code&gt; on &lt;code&gt;ArrayVec&lt;/code&gt; and get &lt;code&gt;ArrayVecIntoIter&lt;/code&gt;, you can continuously call &lt;code&gt;next()&lt;/code&gt; on &lt;code&gt;ArrayVecIntoIter&lt;/code&gt; to iterate through the values in &lt;code&gt;ArrayVec&lt;/code&gt;. That, in a nutshell, is how you make &lt;code&gt;ArrayVec&lt;/code&gt; iterable using &lt;code&gt;IntoIterator&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Before putting all this into practice, below is the code that implements &lt;code&gt;ArrayVec&lt;/code&gt; and it's functionality (as built in &lt;a href="https://dev.to/allwelldotdev/how-to-build-a-heapless-vector-using-maybeuninit-for-better-performance-ojo"&gt;the previous article&lt;/a&gt;). After going through the code and understanding it, we'll start making &lt;code&gt;ArrayVec&lt;/code&gt; iterable.&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;#![no_std]&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="k"&gt;crate&lt;/span&gt; &lt;span class="n"&gt;std&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;arrayvec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ArrayVec&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;arrayvec&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;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;MaybeUninit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;#[derive(Debug)]&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;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&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;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MaybeUninit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&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;N&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="cd"&gt;/// Creates a new empty ArrayVec with an array of uninitialized `T`&lt;/span&gt;
        &lt;span class="cd"&gt;/// and `len` = 0.&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;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ArrayVec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// values: unsafe { MaybeUninit::uninit().assume_init() },&lt;/span&gt;
                &lt;span class="c1"&gt;// Below is same as the commented code above but safer.&lt;/span&gt;
                &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nn"&gt;MaybeUninit&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;uninit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="cd"&gt;/// Pushes `T` if all `N` elements have not been initialized;&lt;/span&gt;
        &lt;span class="cd"&gt;/// else returns `Err(T)`.&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;try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;T&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;if&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&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;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&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="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="cd"&gt;/// Returns a reference to the element at `index` if within bounds&lt;/span&gt;
        &lt;span class="cd"&gt;/// and initialized; else returns `None`.&lt;/span&gt;
        &lt;span class="cd"&gt;///&lt;/span&gt;
        &lt;span class="cd"&gt;/// SAFETY: Unsafe internally: Assumes the first `len` slots are&lt;/span&gt;
        &lt;span class="cd"&gt;/// initialized.&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;T&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;if&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;unsafe&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="o"&gt;&amp;amp;*&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.as_ptr&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="cd"&gt;/// Pops the last value, if any, returning owned `T` (or `None`&lt;/span&gt;
        &lt;span class="cd"&gt;/// if empty).&lt;/span&gt;
        &lt;span class="cd"&gt;///&lt;/span&gt;
        &lt;span class="cd"&gt;/// SAFETY: Uses `.assume_init_read()` to extract (read) and mark&lt;/span&gt;
        &lt;span class="cd"&gt;/// memory as uninitialized (this is also helped by the&lt;/span&gt;
        &lt;span class="cd"&gt;/// decrementing of `self.len` for the next `try_push`).&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;pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&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;if&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&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="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.assume_init_read&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="cd"&gt;/// Getter for current length.&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;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="cd"&gt;/// Return a slice using `slice::from_raw_parts()`. Returns a slice&lt;/span&gt;
        &lt;span class="cd"&gt;/// over initialized elements (i.e. first `self.len` slots).&lt;/span&gt;
        &lt;span class="cd"&gt;///&lt;/span&gt;
        &lt;span class="cd"&gt;/// SAFETY: Unsafe internally, but safe API: assumes invariant holds.&lt;/span&gt;
        &lt;span class="cd"&gt;/// Length points to valid length of init elements.&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;as_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_raw_parts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.values&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;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;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&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="cd"&gt;/// Returns a mutable slice over initialized elements.&lt;/span&gt;
        &lt;span class="cd"&gt;///&lt;/span&gt;
        &lt;span class="cd"&gt;/// SAFETY: Length param is valid length of init elements.&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;as_mut_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;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="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_raw_parts_mut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.values&lt;/span&gt;&lt;span class="nf"&gt;.as_mut_ptr&lt;/span&gt;&lt;span class="p"&gt;()&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;mut&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&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="c1"&gt;// Implement Drop for ArrayVec to safely deallocate initialized elements.&lt;/span&gt;
    &lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Drop&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&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;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="cm"&gt;/* SAFETY: Explicitly drops the first `len` initialized elements.
            Therefore, no double frees. */&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.values&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;.assume_init_drop&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;CAP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&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;main&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;// A:&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;arr_vec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ArrayVec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CAP&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;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nn"&gt;std&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;arr_vec&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// View init ArrayVec&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;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Push a few elements&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CAP&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&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="nn"&gt;std&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;arr_vec&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// View pushed elements&lt;/span&gt;

        &lt;span class="c1"&gt;// Return elements in initialized index.&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;arr_els&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.as_slice&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nn"&gt;std&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="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Init values: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arr_els&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Pop from MaybeUninit ArrayVec; if uninit, return None.&lt;/span&gt;
        &lt;span class="nn"&gt;std&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="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;ArrayVec `len` before pop: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="nn"&gt;std&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;"Popped value: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.pop&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="nn"&gt;std&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;"ArrayVec `len` after pop: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

        &lt;span class="c1"&gt;// TEST: Add more elements beyond `CAP` size for ArrayVec;&lt;/span&gt;
        &lt;span class="c1"&gt;// `try_push` should escape and return with Err.&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;arr_len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;arr_vec&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;arr_len&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="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="cm"&gt;/* I can deref the pointer
        for the value here without moving the value because I know it's a
        primitive value which enables bitwise copy. */&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;arr_err_els&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nb"&gt;i32&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;CAP&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="nn"&gt;ArrayVec&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;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;arr_len&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CAP&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;count&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="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;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;arr_err_els&lt;/span&gt;&lt;span class="nf"&gt;.try_push&lt;/span&gt;&lt;span class="p"&gt;(&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;value&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="p"&gt;}&lt;/span&gt;
        &lt;span class="nn"&gt;std&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="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Filled ArrayVec: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.as_slice&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="nn"&gt;std&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;"Err beyond ArrayVec: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arr_err_els&lt;/span&gt;&lt;span class="nf"&gt;.as_slice&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;&lt;small&gt;Figure 1: Complete former implementation of &lt;code&gt;ArrayVec&lt;/code&gt;.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Having understood the implementation and functionality of &lt;code&gt;ArrayVec&lt;/code&gt;, next we implement &lt;code&gt;IntoIterator&lt;/code&gt; on &lt;code&gt;ArrayVec&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Implementing &lt;code&gt;IntoIterator&lt;/code&gt; for &lt;code&gt;ArrayVec&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;ArrayVec&lt;/code&gt; has two methods, &lt;code&gt;as_slice&lt;/code&gt; and &lt;code&gt;as_mut_slice&lt;/code&gt;, that return a slice of the array. A cool thing about &lt;code&gt;slice&lt;/code&gt; types is they implement methods, &lt;code&gt;iter&lt;/code&gt; and &lt;code&gt;iter_mut&lt;/code&gt;, that let you return an iterator over the slice elements; immutably &lt;code&gt;&amp;amp;&lt;/code&gt; or mutably &lt;code&gt;&amp;amp;mut&lt;/code&gt; referenced, respectively. Let's start by implementing &lt;code&gt;iter&lt;/code&gt; and &lt;code&gt;iter_mut&lt;/code&gt; methods on &lt;code&gt;ArrayVec&lt;/code&gt; to return iterators from slices of &lt;code&gt;ArrayVec&lt;/code&gt;.&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;// ...earlier code.&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...earlier code.&lt;/span&gt;

    &lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&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;// ...earlier code.&lt;/span&gt;

        &lt;span class="cd"&gt;/// Use slice iterator for immutable iteration of ArrayVec.&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;iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Iter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T&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;self&lt;/span&gt;&lt;span class="py"&gt;.as_slice&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="cd"&gt;/// Use slice iterator for mutable iteration of ArrayVec.&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;iter_mut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;IterMut&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T&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;self&lt;/span&gt;&lt;span class="py"&gt;.as_mut_slice&lt;/span&gt;&lt;span class="nf"&gt;.iter_mut&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;&lt;small&gt;Figure 2: Converting slices of &lt;code&gt;ArrayVec&lt;/code&gt; into iterators.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;With this implementation in place, when we call &lt;code&gt;ArrayVec::iter&lt;/code&gt; or &lt;code&gt;ArrayVec::iter_mut&lt;/code&gt;, we'll get a type that is &lt;code&gt;Iterator&lt;/code&gt; and allows us iterate through elements of &lt;code&gt;ArrayVec&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Three things must happen before we can successfully implement &lt;code&gt;IntoIterator&lt;/code&gt; on &lt;code&gt;ArrayVec&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Provide &lt;code&gt;IntoIterator::IntoIter&lt;/code&gt; associated type for &lt;code&gt;ArrayVec&lt;/code&gt; by creating &lt;code&gt;ArrayVecIntoIter&lt;/code&gt; type.&lt;/li&gt;
&lt;li&gt;Implement &lt;code&gt;Iterator&lt;/code&gt; for &lt;code&gt;ArrayVecIntoIter&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Implement &lt;code&gt;Drop&lt;/code&gt; for &lt;code&gt;ArrayVecIntoIter&lt;/code&gt;. &lt;em&gt;You'll see why we do this later.&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;1. Create &lt;code&gt;ArrayVecIntoIter&lt;/code&gt; Type.&lt;/strong&gt;&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;// ...earlier code.&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...earlier code.&lt;/span&gt;

    &lt;span class="c1"&gt;// Build out iterator type for ArrayVec as ArrayVecIntoIter&amp;lt;T, N&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;// Consuming iterator (by-value): Moves out owned T.&lt;/span&gt;
    &lt;span class="c1"&gt;// But will provide iterators for fundamental types: &amp;amp; and &amp;amp;mut&lt;/span&gt;
    &lt;span class="nd"&gt;#[derive(Debug)]&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;ArrayVecIntoIter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&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;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MaybeUninit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&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;N&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&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;&lt;small&gt;Figure 3: Creating &lt;code&gt;ArrayVecIntoIter&lt;/code&gt;—&lt;code&gt;ArrayVec&lt;/code&gt;'s iterator.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Notice &lt;code&gt;ArrayVecIntoIter&lt;/code&gt; is similar in structure to &lt;code&gt;ArrayVec&lt;/code&gt;, only difference being the &lt;code&gt;index&lt;/code&gt; field. This field would be used to track how many initialized elements in &lt;code&gt;values: [MaybeUninit&amp;lt;T&amp;gt;; N]&lt;/code&gt; array have been iterated over.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Implement &lt;code&gt;Iterator&lt;/code&gt; for &lt;code&gt;ArrayVecIntoIter&lt;/code&gt;.&lt;/strong&gt;&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;// ...earlier code.&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...earlier code.&lt;/span&gt;

    &lt;span class="c1"&gt;// Implement Iterator trait on ArrayVecIntoIter making it an iterator.&lt;/span&gt;
    &lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Iterator&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ArrayVecIntoIter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&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;type&lt;/span&gt; &lt;span class="n"&gt;Item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;T&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;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Item&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;if&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.index&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.index&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.index&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="c1"&gt;// SAFETY: i &amp;lt; len, so slot is init&lt;/span&gt;
            &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.values&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;.assume_init_read&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;fn&lt;/span&gt; &lt;span class="nf"&gt;size_hint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;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;let&lt;/span&gt; &lt;span class="n"&gt;remaining&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt;&lt;span class="nf"&gt;.saturating_sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.index&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;remaining&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;remaining&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;&lt;small&gt;Figure 4: Implementing &lt;code&gt;Iterator&lt;/code&gt; for &lt;code&gt;ArrayVecIntoIter&lt;/code&gt;.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Iterator::Item&lt;/code&gt; associated type for &lt;code&gt;ArrayVecIntoIter&amp;lt;T, N&amp;gt;&lt;/code&gt; is &lt;code&gt;T&lt;/code&gt;. We setup two methods, &lt;code&gt;next&lt;/code&gt; and &lt;code&gt;size_hint&lt;/code&gt;. &lt;code&gt;next&lt;/code&gt; is a required &lt;code&gt;Iterator&lt;/code&gt; method and we set it up to return &lt;code&gt;Option&amp;lt;Self::Item&amp;gt;&lt;/code&gt; in other words &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; for &lt;code&gt;ArrayVecIntoIter&amp;lt;T, N&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;next&lt;/code&gt;, we check if the iterator index tracker (&lt;code&gt;self.index&lt;/code&gt;) value equates to the vector initialized element tracker (&lt;code&gt;self.len&lt;/code&gt;), if yes, we return &lt;code&gt;None&lt;/code&gt; immediately because that means, we've reached the end of iteration. That way we create a safe API over unsafe code by not reading uninitialized values (which is undefined behaviour UB). &lt;code&gt;.assume_init_read()&lt;/code&gt; reads the initialized values and returns them owned. This is why we get the return type of &lt;code&gt;Option&amp;lt;Self::Item&amp;gt;&lt;/code&gt;. &lt;code&gt;Self::Item&lt;/code&gt;, which is &lt;code&gt;T&lt;/code&gt;, is an owned value.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Review the &lt;a href="https://dev.to/allwelldotdev/how-to-build-a-heapless-vector-using-maybeuninit-for-better-performance-ojo"&gt;previous article&lt;/a&gt; to understand, in detail, what &lt;code&gt;.assume_init_read()&lt;/code&gt; does as it dereferences and reads the value behind the &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;size_hint&lt;/code&gt; as the name suggests is a method that computes and returns bounds on the remaining length of the iterator. It returns a tuple where the first element is the lower bound, and the second element is the upper bound. To learn more about &lt;code&gt;size_hint&lt;/code&gt;, see the &lt;a href="https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.size_hint" rel="noopener noreferrer"&gt;stdlib docs on &lt;code&gt;Iterator&lt;/code&gt; methods&lt;/a&gt;. We use the value retrieved from this method later on (I'll call your attention back to this then).&lt;/p&gt;

&lt;p&gt;With these two methods implemented, &lt;code&gt;ArrayVecIntoIter&lt;/code&gt; is now an iterator for &lt;code&gt;ArrayVec&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Implement &lt;code&gt;Drop&lt;/code&gt; for &lt;code&gt;ArrayVecIntoIter&lt;/code&gt;.&lt;/strong&gt;&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;// ...earlier code.&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...earlier code.&lt;/span&gt;

    &lt;span class="c1"&gt;// Implement Drop trait to safely deallocate initialized elements&lt;/span&gt;
    &lt;span class="c1"&gt;// from ArrayVecIntoIter&amp;lt;T, N&amp;gt; MaybeUninit&amp;lt;T&amp;gt; values&lt;/span&gt;
    &lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Drop&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ArrayVecIntoIter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&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;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Drop remaining init elements (from index to len)&lt;/span&gt;
            &lt;span class="c1"&gt;// SAFETY: Invariant holds for those slots.&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.index&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.values&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;.assume_init_drop&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;// Uninit slots auto-drop as MaybeUninit: meaning as "garbage"&lt;/span&gt;
            &lt;span class="c1"&gt;// bytes they are overwritten by the next write.&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;&lt;small&gt;Figure 5: Implementing &lt;code&gt;Drop&lt;/code&gt; for &lt;code&gt;ArrayVecIntoIter&lt;/code&gt;.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Next, we implement &lt;code&gt;Drop&lt;/code&gt; for &lt;code&gt;ArrayVecIntoIter&lt;/code&gt; to deallocate initialized elements that have yet to be iterated over, if any. Hence why in the &lt;code&gt;for&lt;/code&gt; loop, we iterate over &lt;code&gt;usize&lt;/code&gt; range of &lt;code&gt;self.index..self.len&lt;/code&gt;. In a scenario where we've iterated through all initialized elements (&lt;code&gt;self.index == self.len&lt;/code&gt;) then &lt;code&gt;.assume_init_drop()&lt;/code&gt; will not be called (therefore no double-frees).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why is it important though to implement &lt;code&gt;Drop&lt;/code&gt; for &lt;code&gt;ArrayVecIntoIter&lt;/code&gt; especially since we already implemented &lt;code&gt;Drop&lt;/code&gt; for &lt;code&gt;ArrayVec&lt;/code&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The reason is because when we convert &lt;code&gt;ArrayVec&lt;/code&gt; into its iterator &lt;code&gt;ArrayVecIntoIter&lt;/code&gt;, fields of &lt;code&gt;ArrayVec&lt;/code&gt; will be moved in the &lt;code&gt;&amp;lt;ArrayVec as IntoIterator&amp;gt;::into_iter&lt;/code&gt; method into similar fields in &lt;code&gt;ArrayVecIntoIter&lt;/code&gt;. Therefore, we need to, as we did for &lt;code&gt;ArrayVec&lt;/code&gt;, manually drop the uninitialized values now moved to &lt;code&gt;ArrayVecIntoIter&lt;/code&gt;. More on this later.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, we can successfully implement &lt;code&gt;IntoIterator&lt;/code&gt; on &lt;code&gt;ArrayVec&lt;/code&gt;.&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;// ...earlier code.&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...earlier code.&lt;/span&gt;

    &lt;span class="c1"&gt;// Finally, implement IntoIterator for ArrayVec; returns&lt;/span&gt;
    &lt;span class="c1"&gt;// an iterator (ArrayVecIntoIter).&lt;/span&gt;
    &lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;IntoIterator&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&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;type&lt;/span&gt; &lt;span class="n"&gt;Item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;T&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;IntoIter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ArrayVecIntoIter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&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;into_iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;IntoIter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Wrap `self` inside ManuallyDrop so ArrayVec Drop cannot&lt;/span&gt;
            &lt;span class="c1"&gt;// be called on ArrayVec. Prevents double-free.&lt;/span&gt;
            &lt;span class="c1"&gt;// Drop will be handled by ArrayVecIntoIter.&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ManuallyDrop&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;self&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="c1"&gt;// SAFETY: Read (bitwise copy) into `values` and `len`,&lt;/span&gt;
            &lt;span class="c1"&gt;// since `self` is consumed by function call; `this` will not&lt;/span&gt;
            &lt;span class="c1"&gt;// be used again.&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;values&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="nn"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;read&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;this&lt;/span&gt;&lt;span class="py"&gt;.values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;len&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="nn"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;read&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;this&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

            &lt;span class="n"&gt;ArrayVecIntoIter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="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;&lt;small&gt;Figure 6: Implementing &lt;code&gt;IntoIterator&lt;/code&gt; for &lt;code&gt;ArrayVec&lt;/code&gt;.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;First observation is that &lt;code&gt;into_iter&lt;/code&gt; consumes &lt;code&gt;self&lt;/code&gt; and returns an iterator: &lt;code&gt;Self::IntoIter&lt;/code&gt; (i.e. &lt;code&gt;&amp;lt;ArrayVec as IntoIterator&amp;gt;::IntoIter&lt;/code&gt;) which points to &lt;code&gt;ArrayVecIntoIter&lt;/code&gt;. This is precisely why we first needed to create the iterator, &lt;code&gt;ArrayVecIntoIter&lt;/code&gt;, for &lt;code&gt;ArrayVec&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As &lt;code&gt;self&lt;/code&gt; is consumed, if we tried to perform a simpler operation by transferring ownership of &lt;code&gt;self&lt;/code&gt;'s values, the compiler would have panicked with an error. Below is an example.&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;// ...earlier code.&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...earlier code.&lt;/span&gt;

    &lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;IntoIterator&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&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;type&lt;/span&gt; &lt;span class="n"&gt;Item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;T&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;IntoIter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ArrayVecIntoIter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&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;into_iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;IntoIter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ArrayVecIntoIter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="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;&lt;small&gt;Figure 7: Rewriting code in Figure 6 in a simpler operation.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Panics with error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  Compiling playground v0.0.1 &lt;span class="o"&gt;(&lt;/span&gt;/playground&lt;span class="o"&gt;)&lt;/span&gt;
error[E0509]: cannot move out of &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;arrayvec::ArrayVec&amp;lt;T, N&amp;gt;&lt;span class="sb"&gt;`&lt;/span&gt;, which implements the &lt;span class="sb"&gt;`&lt;/span&gt;Drop&lt;span class="sb"&gt;`&lt;/span&gt; trait
   &lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; src/main.rs:190:25
    |
190 |                 values: self.values,
    |                         ^^^^^^^^^^^
    |                         |
    |                         cannot move out of here
    |                         move occurs because &lt;span class="sb"&gt;`&lt;/span&gt;self.values&lt;span class="sb"&gt;`&lt;/span&gt; has &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;span class="p"&gt;;&lt;/span&gt; N]&lt;span class="sb"&gt;`&lt;/span&gt;, which does not implement the &lt;span class="sb"&gt;`&lt;/span&gt;Copy&lt;span class="sb"&gt;`&lt;/span&gt; trait

For more information about this error, try &lt;span class="sb"&gt;`&lt;/span&gt;rustc &lt;span class="nt"&gt;--explain&lt;/span&gt; E0509&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
error: could not compile &lt;span class="sb"&gt;`&lt;/span&gt;playground&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;bin &lt;span class="s2"&gt;"playground"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; due to 1 previous error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;Figure 8: Compiler error panic from running code in Figure 7.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;This error states that the compiler cannot move out of &lt;code&gt;self&lt;/code&gt; because &lt;code&gt;self&lt;/code&gt; (&lt;code&gt;ArrayVec&lt;/code&gt;) implements &lt;code&gt;Drop&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Remember, in the &lt;code&gt;Drop&lt;/code&gt; implementation of &lt;code&gt;ArrayVec&lt;/code&gt;, we iterated through a range that had &lt;code&gt;self.len&lt;/code&gt; as the upper bound, and within the iteration we called &lt;code&gt;.assume_init_drop()&lt;/code&gt; on the initialized elements of the &lt;code&gt;self.values&lt;/code&gt; array. Accessing fields of &lt;code&gt;ArrayVec&lt;/code&gt; in &lt;code&gt;drop&lt;/code&gt; is the reason why the error code in &lt;em&gt;Figure 8&lt;/em&gt; occurs in a simple operation in &lt;em&gt;Figure 7&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Because &lt;code&gt;ArrayVec&lt;/code&gt; implements &lt;code&gt;Drop&lt;/code&gt; and, in the implementation, accesses its fields, when we attempt to move out of &lt;code&gt;self&lt;/code&gt; in &lt;code&gt;&amp;lt;ArrayVec as IntoIterator&amp;gt;::into_iter&lt;/code&gt; the compiler panics saying, "Hey, &lt;code&gt;self.values&lt;/code&gt; will be moved out here which means by the time I call &lt;code&gt;drop&lt;/code&gt; on &lt;code&gt;ArrayVec&lt;/code&gt; which is &lt;code&gt;self&lt;/code&gt; when &lt;code&gt;into_iter&lt;/code&gt; finishes running, in &lt;code&gt;&amp;lt;ArrayVec as Drop&amp;gt;::drop&lt;/code&gt; I'll be accessing fields of &lt;code&gt;self&lt;/code&gt; that have had their values moved therefore causing undefined behaviour UB. I cannot allow memory safety errors and UB therefore this is an error and you have to fix this code." Just imagine the compiler was a real person and had this conversation with you.&lt;/p&gt;

&lt;p&gt;The way to fix that error is the reason for the implementation in &lt;em&gt;Figure 7&lt;/em&gt;: by wrapping &lt;code&gt;self&lt;/code&gt; (i.e. &lt;code&gt;ArrayVec&lt;/code&gt;) in &lt;code&gt;core::mem::ManuallyDrop&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ManuallyDrop&lt;/code&gt; wraps &lt;code&gt;ArrayVec&lt;/code&gt; to suppress its &lt;code&gt;Drop&lt;/code&gt; impl during the transfer, then we &lt;code&gt;unsafe&lt;/code&gt;-read fields, using &lt;code&gt;core::ptr::read&lt;/code&gt; (similar in function to &lt;code&gt;MaybeUninit::assume_init_read&lt;/code&gt;), into &lt;code&gt;ArrayVecIntoIter&lt;/code&gt; (the iterator, which takes full ownership). Then we implement &lt;code&gt;Drop&lt;/code&gt; for &lt;code&gt;ArrayVecIntoIter&lt;/code&gt; to deallocate owned values. Finally, &lt;code&gt;ArrayVecIntoIter&lt;/code&gt;'s &lt;code&gt;Drop&lt;/code&gt; and &lt;code&gt;next&lt;/code&gt; handle dropping iterator consumed/unconsumed elements correctly—no leaks, no doubles.&lt;/p&gt;




&lt;p&gt;A lot has been explained already but we've only just iterated over owned values of &lt;code&gt;ArrayVec&lt;/code&gt;. We also need to be able to iterate over borrowed values. Usually known as fundamental types (&lt;code&gt;&amp;amp;&lt;/code&gt; and &lt;code&gt;&amp;amp;mut&lt;/code&gt;). Let's do that next.&lt;/p&gt;

&lt;h4&gt;
  
  
  Implementing &lt;code&gt;IntoIterator&lt;/code&gt; for &lt;code&gt;&amp;amp;ArrayVec&lt;/code&gt; and &lt;code&gt;&amp;amp;mut ArrayVec&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;This is simpler than enabling iteration for owned values. Here, we simply call the &lt;code&gt;iter&lt;/code&gt; and &lt;code&gt;iter_mut&lt;/code&gt; methods on &lt;code&gt;ArrayVec&lt;/code&gt; and return a slice iterator.&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;// ...earlier code.&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...earlier code.&lt;/span&gt;

    &lt;span class="c1"&gt;// Implement IntoIterator for fundamental types of ArrayVec: &amp;amp; and &amp;amp;mut.&lt;/span&gt;
    &lt;span class="c1"&gt;// By reference: yields &amp;amp;T&lt;/span&gt;
    &lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;IntoIterator&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&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;type&lt;/span&gt; &lt;span class="n"&gt;Item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="n"&gt;T&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;IntoIter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Iter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T&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;into_iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;IntoIter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.as_slice&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="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// By mutable reference: yields &amp;amp;mut T&lt;/span&gt;
    &lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;IntoIterator&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&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;type&lt;/span&gt; &lt;span class="n"&gt;Item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;T&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;IntoIter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;IterMut&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T&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;into_iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;IntoIter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.as_mut_slice&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.iter_mut&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;&lt;small&gt;Figure 9: Implementing &lt;code&gt;IntoIterator&lt;/code&gt; for fundamental types of &lt;code&gt;ArrayVec&lt;/code&gt;.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;As you can see, it's a much simpler implementation to that of owned values. In real-word use cases, iterating over borrowed values or values that exist in the buffer, in embedded contexts usually fulfills 80% of your needs. Since in embedded contexts, due to limited compute resources, consumption (or in Rust terms, moving) of values is discouraged while reusing the buffer is encouraged.&lt;/p&gt;

&lt;h4&gt;
  
  
  Testing
&lt;/h4&gt;

&lt;p&gt;With the previous implementations, &lt;code&gt;ArrayVec&lt;/code&gt; is now iterable in a &lt;code&gt;for&lt;/code&gt; loop. Let's test it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_std]&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="k"&gt;crate&lt;/span&gt; &lt;span class="n"&gt;std&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;arrayvec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ArrayVec&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;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ...`ArrayVec` implementation. */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;CAP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&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;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// { /* A: ...earlier code */ }&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// B:&lt;/span&gt;
        &lt;span class="c1"&gt;// Iterating over ArrayVec through fundamental types: &amp;amp; and &amp;amp;mut&lt;/span&gt;

        &lt;span class="c1"&gt;// Shared iteration&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;arr_vec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ArrayVec&lt;/span&gt;&lt;span class="p"&gt;::&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="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CAP&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;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;count&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="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;CAP&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&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;// Init values on ArrayVec&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nn"&gt;std&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;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;arr_vec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nn"&gt;std&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;"ArrayVec at index {}: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count&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;count&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="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Mutable iteration&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;in&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;arr_vec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nn"&gt;std&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="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Mutated ArrayVec: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.as_slice&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;// C:&lt;/span&gt;
        &lt;span class="c1"&gt;// Iterating over owned values of ArrayVec by calling `into_iter`&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;arr_vec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ArrayVec&lt;/span&gt;&lt;span class="p"&gt;::&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="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CAP&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;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;count&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="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CAP&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="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&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="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;arr_iter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.into_iter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// move arr_vec&lt;/span&gt;
        &lt;span class="c1"&gt;// std::println!("{:?}", arr_vec); // should return move error&lt;/span&gt;
        &lt;span class="cm"&gt;/* Above code confirms `impl IntoIterator for ArrayVec` safety
        invariants.
        */&lt;/span&gt;
        &lt;span class="nn"&gt;std&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="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;arr_iter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="cm"&gt;/* View created
        ArrayVecIntoIter. See `len` and `index` fields.
        */&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;arr_vec2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ArrayVec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CAP&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;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* Loop through calls to `next()` to iterate through
        ArrayVecIntoInter.
        */&lt;/span&gt;
            &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;arr_iter&lt;/span&gt;&lt;span class="nf"&gt;.next&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;val&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;arr_vec2&lt;/span&gt;&lt;span class="nf"&gt;.try_push&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;val&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="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="n"&gt;arr_vec2&lt;/span&gt;&lt;span class="nf"&gt;.try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;None&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="k"&gt;break&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="nn"&gt;std&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;arr_iter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="cm"&gt;/* Review `len` and `index` fields.
        Notice index incr caused by calling `next()` on ArrayVecIntoIter.
        */&lt;/span&gt;
        &lt;span class="nn"&gt;std&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;arr_vec2&lt;/span&gt;&lt;span class="nf"&gt;.as_slice&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;&lt;small&gt;Figure 10: Testing the iteration of &lt;code&gt;ArrayVec&lt;/code&gt; in a &lt;code&gt;for&lt;/code&gt; loop for fundamental types and owned values.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;In Scope &lt;code&gt;B&lt;/code&gt;, we test for iteration through fundamentals types. While in Scope &lt;code&gt;C&lt;/code&gt;, we test for iteration over owned values.&lt;/p&gt;

&lt;p&gt;After running the code in &lt;em&gt;Figure 10&lt;/em&gt; with &lt;code&gt;cargo run&lt;/code&gt;, we get:&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;# ...earlier output.&lt;/span&gt;
&lt;span class="nt"&gt;---&lt;/span&gt;
ArrayVec at index 0: 1
ArrayVec at index 1: 2
ArrayVec at index 2: 3
ArrayVec at index 3: 4
ArrayVec at index 4: 5
&lt;span class="nt"&gt;---&lt;/span&gt;
Mutated ArrayVec: &lt;span class="o"&gt;[&lt;/span&gt;11, 12, 13, 14, 15]
&lt;span class="nt"&gt;---&lt;/span&gt;
ArrayVecIntoIter &lt;span class="o"&gt;{&lt;/span&gt; values: &lt;span class="o"&gt;[&lt;/span&gt;MaybeUninit&amp;lt;u8&amp;gt;, MaybeUninit&amp;lt;u8&amp;gt;, MaybeUninit&amp;lt;u8&amp;gt;, MaybeUninit&amp;lt;u8&amp;gt;, MaybeUninit&amp;lt;u8&amp;gt;], len: 4, index: 0 &lt;span class="o"&gt;}&lt;/span&gt;
ArrayVecIntoIter &lt;span class="o"&gt;{&lt;/span&gt; values: &lt;span class="o"&gt;[&lt;/span&gt;MaybeUninit&amp;lt;u8&amp;gt;, MaybeUninit&amp;lt;u8&amp;gt;, MaybeUninit&amp;lt;u8&amp;gt;, MaybeUninit&amp;lt;u8&amp;gt;, MaybeUninit&amp;lt;u8&amp;gt;], len: 4, index: 4 &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;Some&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;2&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;3&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;4&lt;span class="o"&gt;)&lt;/span&gt;, None]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;Figure 11: Terminal return from running code in Figure 10.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;In Scope &lt;code&gt;C&lt;/code&gt;, when we call &lt;code&gt;into_iter()&lt;/code&gt; on &lt;code&gt;arr_vec&lt;/code&gt;, &lt;code&gt;arr_vec&lt;/code&gt; is moved yet there's no panic for a &lt;code&gt;Drop&lt;/code&gt; on &lt;code&gt;arr_vec&lt;/code&gt; because we wrapped &lt;code&gt;arr_vec&lt;/code&gt; in a &lt;code&gt;ManuallyDrop&amp;lt;T&amp;gt;&lt;/code&gt; in the &lt;code&gt;&amp;lt;ArrayVec as IntoIterator&amp;gt;::into_iter&lt;/code&gt; method. Because the consumption of &lt;code&gt;self&lt;/code&gt;, the invariants in &lt;code&gt;into_iter&lt;/code&gt; are upheld because &lt;code&gt;arr_vec&lt;/code&gt; can no longer be used after the move. This is one of the awesome characteristics of the Rust programming language. Its ability to enforce memory safety through types and the borrow checker.&lt;/p&gt;

&lt;p&gt;Some other things you also see in play after the test like the &lt;code&gt;index&lt;/code&gt; field of the &lt;code&gt;ArrayVec&lt;/code&gt; iterator (&lt;code&gt;ArrayVecIntoIter&lt;/code&gt;).&lt;/p&gt;




&lt;p&gt;We've learned about &lt;code&gt;IntoIterator&lt;/code&gt; and &lt;code&gt;Iterator&lt;/code&gt;, and how to implement them. Next, we'll look at &lt;code&gt;FromIterator&lt;/code&gt; and &lt;code&gt;Extend&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;FromIterator&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;FromIterator&lt;/code&gt; trait, when implemented on your custom type, allows you to fill your custom &lt;em&gt;collection&lt;/em&gt; type with output from another iterator. It does this by showing your custom &lt;em&gt;collection&lt;/em&gt; type how to fill itself with outputs from another iterator, of course this is implemented in code.&lt;/p&gt;

&lt;p&gt;A simple way to understand this is the &lt;code&gt;collect&lt;/code&gt; method on &lt;code&gt;T&lt;/code&gt;, where &lt;code&gt;T: Iterator&lt;/code&gt;. The &lt;code&gt;collect&lt;/code&gt; method &lt;em&gt;collects&lt;/em&gt; outputs of an iterator into a collection type (like &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt;, etc.). The &lt;code&gt;collect&lt;/code&gt; method actually uses the &lt;code&gt;FromIterator&lt;/code&gt; trait behind the scenes by calling the &lt;code&gt;FromIterator::from_iter&lt;/code&gt; method on the &lt;em&gt;collection&lt;/em&gt; type it's collecting the iterator outputs into, thereby filling the type.&lt;/p&gt;

&lt;p&gt;Seeing the code will help you understand it better.&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;// ...earlier code.&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...earlier code.&lt;/span&gt;

    &lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;FromIterator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&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="n"&gt;from_iter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;I&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;iter&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="k"&gt;Self&lt;/span&gt;
        &lt;span class="k"&gt;where&lt;/span&gt;
            &lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;IntoIterator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;T&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;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;iter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;iter&lt;/span&gt;&lt;span class="nf"&gt;.into_iter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="c1"&gt;// Optimize: If hinted size &amp;gt; N, take only N to skip&lt;/span&gt;
            &lt;span class="c1"&gt;// early access.&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&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;iter&lt;/span&gt;&lt;span class="nf"&gt;.size_hint&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;lower&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;N&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;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;iter&lt;/span&gt;&lt;span class="nf"&gt;.take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.try_push&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="cm"&gt;/* Won't fail as
                    len &amp;lt; N.
                    */&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="c1"&gt;// General case: Push until full (truncates excess).&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;iter&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;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.try_push&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="cm"&gt;/* Err(item) dropped
                if full.
                */&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;arr_vec&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;&lt;small&gt;Figure 12: Implementing &lt;code&gt;FromIterator&lt;/code&gt; for &lt;code&gt;ArrayVec&lt;/code&gt;.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;FromIterator&lt;/code&gt; implementation is a little more generic compared to the &lt;code&gt;IntoIterator&lt;/code&gt; impl for &lt;code&gt;ArrayVec&lt;/code&gt;. Here, &lt;code&gt;FromIterator&lt;/code&gt; is generic over &lt;code&gt;T&lt;/code&gt; which means the output of the iterator must be the same type as the elements inserted in the &lt;code&gt;ArrayVec&lt;/code&gt; collection.&lt;/p&gt;

&lt;p&gt;We see the use of the &lt;code&gt;size_hint&lt;/code&gt; method as it's used to check the lower bound of the iterator (&lt;code&gt;iter&lt;/code&gt;); if more than &lt;code&gt;N&lt;/code&gt;, we take &lt;code&gt;N&lt;/code&gt; capacity from it otherwise we simply iterate through &lt;code&gt;iter&lt;/code&gt;, fill and return &lt;code&gt;Self&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Testing
&lt;/h4&gt;

&lt;p&gt;Testing &lt;code&gt;FromIterator&lt;/code&gt; will be the shortest test because it's s straight forward, simpler process, but one that will help you understand how &lt;code&gt;collect&lt;/code&gt; works under the hood.&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;#![no_std]&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="k"&gt;crate&lt;/span&gt; &lt;span class="n"&gt;std&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;arrayvec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ArrayVec&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;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ...`ArrayVec` implementation. */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;CAP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&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;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// { /* A: ...earlier code */ }&lt;/span&gt;
    &lt;span class="c1"&gt;// { /* B: ...earlier code */ }&lt;/span&gt;
    &lt;span class="c1"&gt;// { /* C: ...earlier code */ }&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// D:&lt;/span&gt;
        &lt;span class="c1"&gt;// Test FromIterator implementation with iterators on ArrayVec.&lt;/span&gt;

        &lt;span class="c1"&gt;// Using collect:&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="py"&gt;.collect&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;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nn"&gt;std&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="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;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.as_slice&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

        &lt;span class="c1"&gt;// Using from_iter:&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ArrayVec&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;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&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;from_iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;i8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="cm"&gt;/* Using
        type inference for `T` in `ArrayVec&amp;lt;T, N&amp;gt;` helped by type cast
        on iterator.
        */&lt;/span&gt;
        &lt;span class="nn"&gt;std&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;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.as_slice&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;&lt;small&gt;Figure 13: Testing &lt;code&gt;FromIterator&lt;/code&gt; implementation on &lt;code&gt;ArrayVec&lt;/code&gt;.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Returns:&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;# ...earlier code.&lt;/span&gt;
&lt;span class="nt"&gt;---&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;-10&lt;/span&gt;, &lt;span class="nt"&gt;-9&lt;/span&gt;, &lt;span class="nt"&gt;-8&lt;/span&gt;, &lt;span class="nt"&gt;-7&lt;/span&gt;, &lt;span class="nt"&gt;-6&lt;/span&gt;, &lt;span class="nt"&gt;-5&lt;/span&gt;, &lt;span class="nt"&gt;-4&lt;/span&gt;, &lt;span class="nt"&gt;-3&lt;/span&gt;, &lt;span class="nt"&gt;-2&lt;/span&gt;, &lt;span class="nt"&gt;-1&lt;/span&gt;, 0, 1, 2, 3, 4]
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;-3&lt;/span&gt;, &lt;span class="nt"&gt;-2&lt;/span&gt;, &lt;span class="nt"&gt;-1&lt;/span&gt;, 0, 1]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;Figure 14: Terminal return from running code in Figure 13.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Notice in &lt;em&gt;Figure 13&lt;/em&gt; that &lt;code&gt;from_iter&lt;/code&gt; can be used either indirectly through &lt;code&gt;collect&lt;/code&gt; or directly as an associated function (i.e. &lt;code&gt;&amp;lt;YourCustomType as FromIterator&amp;gt;::from_iter&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Extend&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Extend&lt;/code&gt; is a shorter implementation compared to &lt;code&gt;FromIterator&lt;/code&gt; that also benefits from &lt;code&gt;IntoIterator&lt;/code&gt;. &lt;code&gt;Extend&lt;/code&gt; is pretty intuitive for its use in that it enables you extend a collection with the contents of an iterator.&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;// ...earlier code.&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...earlier code.&lt;/span&gt;

    &lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Extend&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&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="n"&gt;extend&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;IntoIterator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;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="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;iter&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="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;iter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Stops iterating when `iter` is consumed&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;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="nf"&gt;.try_push&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="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* break if
                `self` is full
                */&lt;/span&gt;
                    &lt;span class="k"&gt;break&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="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;small&gt;Figure 15: Implementing &lt;code&gt;Extend&lt;/code&gt; for &lt;code&gt;ArrayVec&lt;/code&gt;.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Extend::extend&lt;/code&gt; method takes a mutable reference of self (&lt;code&gt;&amp;amp;mut self&lt;/code&gt;) and a type that is iterable (&lt;code&gt;iter&lt;/code&gt;), iterates through &lt;code&gt;iter&lt;/code&gt; and pushes its items into &lt;code&gt;self&lt;/code&gt;. Pretty straight forward right? Told you.&lt;/p&gt;

&lt;p&gt;Before testing &lt;code&gt;Extend&lt;/code&gt;, I want to add a functionality to &lt;code&gt;ArrayVec&lt;/code&gt; that allows us to see which elements in the array are initialized, represented as &lt;code&gt;Some(T)&lt;/code&gt;, and which are uninitialized, represented as &lt;code&gt;None&lt;/code&gt;. If you recognized it, you're right. It's similar to the function of the &lt;code&gt;as_slice&lt;/code&gt; method in &lt;code&gt;ArrayVec&lt;/code&gt; but slightly different in that it doesn't add uninitialized slots to the slice (as it shouldn't). With this new function, which I want to call &lt;code&gt;show_init&lt;/code&gt;, we'll be able to see both initialized and uninitialized slots of the &lt;code&gt;ArrayVec&lt;/code&gt; fixed-size array, as &lt;code&gt;Some(T)&lt;/code&gt; and &lt;code&gt;None&lt;/code&gt; respectively.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To understand why we're trying to see the initialized and uninitialized values of &lt;code&gt;ArrayVec&lt;/code&gt;, see &lt;a href="https://dev.to/allwelldotdev/how-to-build-a-heapless-vector-using-maybeuninit-for-better-performance-ojo"&gt;the previous article&lt;/a&gt; to learn more.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The only caveat of &lt;code&gt;show_init&lt;/code&gt; is that it only works where &lt;code&gt;T&lt;/code&gt; in &lt;code&gt;ArrayVec&amp;lt;T, N&amp;gt;&lt;/code&gt; is copyable (&lt;code&gt;T: Copy&lt;/code&gt;). This is the norm for primitive types but not more so for heap-alloc values. Fortunately for us, we're working in a no_std/embedded context where heap-alloc values are mostly prohibited. The reason for this constraint on &lt;code&gt;show_init&lt;/code&gt; is because within its implementation, we dereference &lt;code&gt;T&lt;/code&gt; to perform a bitwise copy of its value to another memory location. If &lt;code&gt;T&lt;/code&gt; is not copyable (i.e. &lt;code&gt;T: Clone&lt;/code&gt;), &lt;code&gt;T&lt;/code&gt; will be moved, which is UB and foundational to use-after-free or double-free errors. We want to avoid that and enforce only copyable types in our code, therefore we add a trait bound in a where clause, &lt;code&gt;T: Copy&lt;/code&gt;.&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;// ...earlier code.&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...earlier code.&lt;/span&gt;

    &lt;span class="c1"&gt;// Implement these only where `T` is `Copy`.&lt;/span&gt;
    &lt;span class="cm"&gt;/* Better this way because in some impls we dereference `T`;
    if `T` is not `Copy` we'll be creating a use-after-free or
    double-free which is UB.
    */&lt;/span&gt;
    &lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&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;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Copy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="cd"&gt;/// Returns Self with a view of initialized and uninitialized&lt;/span&gt;
        &lt;span class="cd"&gt;/// accesses of memory.&lt;/span&gt;
        &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;show_init&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="o"&gt;&amp;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="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&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;N&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;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;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;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="nf"&gt;.try_push&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="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="cm"&gt;/* deref `T` to copy
                primitive value.
                */&lt;/span&gt;
                &lt;span class="n"&gt;count&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="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;N&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;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="nf"&gt;.try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;count&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="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="nf"&gt;.as_slice&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;&lt;small&gt;Figure 16: Adding &lt;code&gt;show_init&lt;/code&gt; method to &lt;code&gt;ArrayVec&lt;/code&gt; for improved testing utility.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;I won't go into the depth of explaining lifetimes in Rust and why &lt;code&gt;show_init&lt;/code&gt; is generic for the lifetime &lt;code&gt;'a&lt;/code&gt; , but I'll say this much: the lifetime of the return type of &lt;code&gt;show_init&lt;/code&gt; is valid for as long as the owned type passed into the &lt;code&gt;other&lt;/code&gt; argument is valid (in other words, for as long as the lifetime of &lt;code&gt;T&lt;/code&gt; in &lt;code&gt;other: &amp;amp;mut T&lt;/code&gt; is valid).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To fully understand lifetimes in Rust, I recommend reading &lt;a href="https://rust-book.cs.brown.edu/ch10-03-lifetime-syntax.html" rel="noopener noreferrer"&gt;the lifetime chapter in TRPL Book&lt;/a&gt; and &lt;a href="https://doc.rust-lang.org/nomicon/subtyping.html" rel="noopener noreferrer"&gt;lifetime variance in the Rustonomicon&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Testing
&lt;/h4&gt;

&lt;p&gt;With all this in place, let's test our &lt;code&gt;Extend&lt;/code&gt; implementation.&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;#![no_std]&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="k"&gt;crate&lt;/span&gt; &lt;span class="n"&gt;std&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;arrayvec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ArrayVec&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;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ...`ArrayVec` implementation. */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;CAP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&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;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// { /* A: ...earlier code */ }&lt;/span&gt;
    &lt;span class="c1"&gt;// { /* B: ...earlier code */ }&lt;/span&gt;
    &lt;span class="c1"&gt;// { /* C: ...earlier code */ }&lt;/span&gt;
    &lt;span class="c1"&gt;// { /* D: ...earlier code */ }&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// E:&lt;/span&gt;
        &lt;span class="c1"&gt;// Test Extend implementation with iterators on ArrayVec.&lt;/span&gt;

        &lt;span class="cm"&gt;/* Testing for two scenarios;

        1. `arr_vec1` has more CAP (array "capacity" - N) than `arr_vec2`
        has elements to fill it. Meaning, `arr_vec1` will retain spare CAP.

        2. `arr_vec1` has less CAP (array "capacity" - N) than `arr_vec2`
        has elements to fill it. Meaning, `arr_vec1` will max it's CAP
        without extending all of `arr_vec2`s elements.
        */&lt;/span&gt;

        &lt;span class="c1"&gt;// Scenario 1:&lt;/span&gt;
        &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;ArrayVecCap10&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&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;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&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;type&lt;/span&gt; &lt;span class="n"&gt;ArrayVecCap5&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&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;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&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;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;arr_vec1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ArrayVecCap10&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="nn"&gt;ArrayVec&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;count&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="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Add elements to `arr_vec1`.&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;arr_vec1&lt;/span&gt;&lt;span class="nf"&gt;.try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&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="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;arr_vec2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ArrayVecCap5&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="nn"&gt;ArrayVec&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;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Add elements to `arr_vec2`.&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;arr_vec2&lt;/span&gt;&lt;span class="nf"&gt;.try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&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="n"&gt;arr_vec1&lt;/span&gt;&lt;span class="nf"&gt;.extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr_vec2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Extend moves `arr_vec2`.&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;empty_arr_vec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ArrayVecCap10&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ArrayVec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nn"&gt;std&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="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;arr_vec1&lt;/span&gt;&lt;span class="nf"&gt;.show_init&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;empty_arr_vec&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;empty_arr_vec&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="cm"&gt;/* Choosing to explicity drop (or free, or
        deallocate) the stack memory consumed by `empty_arr_vec` here
        as it's no longer in use.
        */&lt;/span&gt;

        &lt;span class="c1"&gt;// Scenario 2:&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;arr_vec1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ArrayVecCap5&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ArrayVec&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;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;arr_vec1&lt;/span&gt;&lt;span class="nf"&gt;.try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;i8&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="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;arr_vec2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ArrayVecCap10&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ArrayVec&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;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;arr_vec2&lt;/span&gt;&lt;span class="nf"&gt;.try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;i8&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="n"&gt;arr_vec1&lt;/span&gt;&lt;span class="nf"&gt;.extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr_vec2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Extend moves `arr_vec2`.&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;empty_arr_vec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ArrayVecCap5&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ArrayVec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nn"&gt;std&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;arr_vec1&lt;/span&gt;&lt;span class="nf"&gt;.show_init&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;empty_arr_vec&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="cm"&gt;/* Don't need to explicity drop `empty_arr_vec` here as before
        because this is the end of the scope, and the Rust Compiler (rustc)
        will call the drop method in ArrayVec's destructor `Drop`
        to drop `empty_arr_vec` implicity.
        */&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;small&gt;Figure 17: Testing the implementation of &lt;code&gt;Extend&lt;/code&gt; for &lt;code&gt;ArrayVec&lt;/code&gt;, and a few other examples.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Returns:&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;# ...earlier output.&lt;/span&gt;
&lt;span class="nt"&gt;---&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;Some&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;2&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;3&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;2&lt;span class="o"&gt;)&lt;/span&gt;, None, None, None, None, None]
&lt;span class="o"&gt;[&lt;/span&gt;Some&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;-2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;-1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;-5&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;-4&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;-3&lt;/span&gt;&lt;span class="o"&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;Figure 18: Terminal return from running code in Figure 17.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;We introduce type aliasing in Rust using &lt;code&gt;ArrayVecCap10&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;ArrayVecCap5&amp;lt;T&amp;gt;&lt;/code&gt;, reducing repeatability, improving readability.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;Scenario 1&lt;/code&gt;, we extend &lt;code&gt;arr_vec1&lt;/code&gt; with &lt;code&gt;arr_vec2&lt;/code&gt; but not fill it up, leaving some slots uninitialized, therefore &lt;code&gt;show_init&lt;/code&gt; returns a shared slice displaying &lt;code&gt;Some(u8)&lt;/code&gt; for initialized slots and &lt;code&gt;None&lt;/code&gt; for uninitialized slots, as planned and implemented. All's good.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;Scenario 2&lt;/code&gt;, we do the opposite extending &lt;code&gt;arr_vec1&lt;/code&gt; with &lt;code&gt;arr_vec2&lt;/code&gt; filling it up but not iterating over all the items of &lt;code&gt;arr_vec2&lt;/code&gt; as &lt;code&gt;arr_vec1&lt;/code&gt;'s capacity buffer had been reached. Showing our implementation of &lt;code&gt;Extend::extend&lt;/code&gt; works.&lt;/p&gt;

&lt;p&gt;Test successful.&lt;/p&gt;

&lt;h2&gt;
  
  
  In conclusion
&lt;/h2&gt;

&lt;p&gt;I wasn't planning for this article to be 5,000+ words (as &lt;a href="https://dev.to/allwelldotdev/how-to-build-a-heapless-vector-using-maybeuninit-for-better-performance-ojo"&gt;the previous article&lt;/a&gt;), well, here we are 😅, but I'm happy I divulged as much useful information as possible, here, to help you improve your understanding of iterators in Rust. If you read till the end give yourself a pat on the back, and thank you for reading my content.&lt;/p&gt;

&lt;p&gt;This article ends the experiment of building heapless data structures and learning from them. There is a well known Rust crate that takes the concepts we've implemented here and in the previous article to build and offer battle-tested heapless data structures useful in no_std and embedded environments. The Rust crate is called &lt;a href="https://crates.io/crates/heapless" rel="noopener noreferrer"&gt;&lt;code&gt;heapless&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can find and play around with the full code on Rust Playground via this link: &lt;a href="https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=7b80863ed153627d1d86a6ee41a42167" rel="noopener noreferrer"&gt;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=7b80863ed153627d1d86a6ee41a42167&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;You can also find the whole code on this GitHub Gist: &lt;a href="https://gist.github.com/allwelldotdev/39c817ca8d40fe5aeb808eb6301a18ff" rel="noopener noreferrer"&gt;https://gist.github.com/allwelldotdev/39c817ca8d40fe5aeb808eb6301a18ff&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;👏🏾 Kudos for finishing the article.&lt;/p&gt;

&lt;p&gt;Hi there! I'm Allwell, a passionate Rust developer currently working from Lagos, Nigeria. You can connect with me on X (&lt;a href="https://x.com/allwelldotdev/" rel="noopener noreferrer"&gt;&lt;code&gt;@allwelldotdev&lt;/code&gt;&lt;/a&gt;) or LinkedIn (&lt;a href="https://linkedin.com/in/allwelldotdev/" rel="noopener noreferrer"&gt;Allwell Agwu-Okoro&lt;/a&gt;). Let's build and learn Rust together.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>software</category>
    </item>
    <item>
      <title>How to build a Heapless Vector using `MaybeUninit&lt;T&gt;` for Better Performance.</title>
      <dc:creator>Allwell</dc:creator>
      <pubDate>Tue, 04 Nov 2025 12:37:22 +0000</pubDate>
      <link>https://dev.to/allwelldotdev/how-to-build-a-heapless-vector-using-maybeuninit-for-better-performance-ojo</link>
      <guid>https://dev.to/allwelldotdev/how-to-build-a-heapless-vector-using-maybeuninit-for-better-performance-ojo</guid>
      <description>&lt;p&gt;Finally understand &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; and why it offers better performance over &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt;, and learn to safeguard unsafe Rust with safe APIs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL:DR&lt;/strong&gt;: Heapless Vector in no_std Rust.&lt;/p&gt;

&lt;p&gt;Rust stores data on the stack (fast, fixed-size), heap (growable but needs alloc), or static (program-long); for memory-tight embedded systems, use &lt;code&gt;#![no_std]&lt;/code&gt; to ditch heap-alloc like &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; and build a "heapless vector" on stack with a fixed-size array &lt;code&gt;[T; N]&lt;/code&gt; tracked by &lt;code&gt;len&lt;/code&gt;. Start safe with &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; (extra space for &lt;code&gt;None&lt;/code&gt; tracking), then optimize to &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; (exact &lt;code&gt;T&lt;/code&gt; size, no overhead) using unsafe methods like &lt;code&gt;write()&lt;/code&gt;, &lt;code&gt;as_ptr()&lt;/code&gt;, &lt;code&gt;assume_init_read()&lt;/code&gt;, and custom &lt;code&gt;Drop&lt;/code&gt;—gains 1.5–2x speed and half memory overhead, but requires careful invariants in unsafe Rust to avoid undefined behaviour. (Generated with AI, Grok.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this article, I'll teach you how to build a heapless vector data structure with the example of one I already built. I'll share the performance benefits and unsafety to look out for and avoid when using &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; over &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt;. Lastly, I'll show you how to build safe APIs on top of unsafe Rust code to ensure "safe unsafe code" in Rust.&lt;/p&gt;

&lt;p&gt;A little primer on Rust memory models before we begin. Though to fully comprehend this article you may require practical understanding of Rust memory models—what's stored where, how, and what for—here's a little primer incase you're new to this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rust's Memory Model
&lt;/h2&gt;

&lt;p&gt;Rust models memory in three main spaces or regions; the &lt;em&gt;stack&lt;/em&gt;, the &lt;em&gt;heap&lt;/em&gt;, and &lt;em&gt;static memory&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;stack&lt;/em&gt; is a short-lived, fixed-size memory region with LIFO (Last In First Out) movement. The stack stores data of function-local variables, primitive types, function parameters, and fixed-size collections like an array. When a function is called a contiguous chunk of memory is allocated to the top of the stack known as a &lt;em&gt;frame&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;heap&lt;/em&gt; is a dynamic, growable region of contiguous memory. Collections and data in the heap are growable and variably-sized. The heap isn't tied to the current call stack (i.e. &lt;code&gt;main&lt;/code&gt; function stack frame) of the program, meaning data in the heap can live forever until explicitly deallocated.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Static memory&lt;/em&gt; is a catch-all term for several closely related regions located in the file your program is compiled into. These regions are automatically loaded into your program's memory when that program is executed. Values in static memory live for the entire execution of your program (as described by Jon Gjengset in Rust for Rustaceans). Static memory stores source code, &lt;code&gt;'static&lt;/code&gt; lifetime values, and values in &lt;code&gt;static&lt;/code&gt; variables. Static memory is read-only by default, therefore immutable. Mutating data in static memory is unsafe (e.g. mutating static variables using &lt;code&gt;static mut&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;How does data behave in these different memory regions? We've already seen some examples in the paragraph on the &lt;em&gt;heap&lt;/em&gt;, discussing further:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data in the stack is allocated/deallocated automatically (LIFO order) when entering/exiting scopes (i.e. function stack frames). Access is very fast. Data size must be known at compile time. No manual management of stack data in Rust (&lt;em&gt;this is what we'll be building in this article using&lt;/em&gt; &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; &lt;em&gt;as an example&lt;/em&gt;).

&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;let x: i32 = 42;&lt;/code&gt; – &lt;code&gt;x&lt;/code&gt; lives on the stack during its scope.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Data in the heap is allocated at runtime. Generally slower than the stack due to pointer indirection and potential fragmentation. Is managed using smart pointers (e.g. &lt;code&gt;Box&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;Rc&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;Arc&amp;lt;T&amp;gt;&lt;/code&gt;, etc.) with Rust's ownership system ensuring safety.

&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;let v = vec![1, 2, 3];&lt;/code&gt; – the vector's buffer is on the heap.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Data in static memory is allocated at compile time into the program's binary with a fixed memory address. Immutable by default, as we talked about, and mutable with unsafe code. The data's lifetime starts when the program starts and ends when the program ends.

&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;static HELLO: &amp;amp;str = "Hello";&lt;/code&gt; – &lt;code&gt;HELLO&lt;/code&gt; is stored statically and accessible anywhere.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Hope you enjoyed that primer because now we move onto answering the question: why would we need a heapless vector data structure in the first place?&lt;/p&gt;

&lt;h2&gt;
  
  
  Rust without the Standard Library
&lt;/h2&gt;

&lt;p&gt;There's a practice in Rust known as "Rust without the standard library" communicated in code with the crate attribute &lt;code&gt;#![no_std]&lt;/code&gt;. To answer our earlier question, we need to understand this practice. &lt;/p&gt;

&lt;p&gt;Usually when you write, build and run Rust code, you most likely do it on a platform with an operating system and a sizeable amount of both RAM memory and disk space (i.e. your laptop or remote server). And sometimes, you write Rust code that is to be executed in environments without an operating system and with limited memory and storage size. This is usually the case when you build for embedded systems, where the code is closer to the bare metal (metaphorically to mean a microcontroller or an SoC). Furthermore, in these "unorthodox" environments, such as those without an operating system, or those without the ability to dynamically allocate memory; how does Rust, as a low level systems programming language, enable us build software that runs in these environments? Through the "Rust without the standard library" (&lt;code&gt;#![no_std]&lt;/code&gt;) practice. Let's elaborate further on how it works.&lt;/p&gt;

&lt;p&gt;By default, Rust comes packaged with the standard library &lt;code&gt;std&lt;/code&gt; and library preludes that bring into scope popularly-used types like &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;Result&amp;lt;T&amp;gt;&lt;/code&gt;; traits like &lt;code&gt;Iterator&lt;/code&gt;, &lt;code&gt;Debug&lt;/code&gt;, &lt;code&gt;Clone&lt;/code&gt;, &lt;code&gt;Drop&lt;/code&gt;; functions like &lt;code&gt;std::mem::drop&lt;/code&gt;, &lt;code&gt;std::mem::size_of&lt;/code&gt;; and macros like &lt;code&gt;std::println!&lt;/code&gt; and &lt;code&gt;std::dbg!&lt;/code&gt;. What you may not know about the standard library is that it is a composite makeup of two of Rust's more fundamental libraries &lt;code&gt;core&lt;/code&gt; and &lt;code&gt;alloc&lt;/code&gt;. In fact, many types and functions in &lt;code&gt;std&lt;/code&gt; are just re-exports from those two libraries.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;alloc&lt;/code&gt; is Rust's dynamic memory allocation library. It's what makes heap allocation data types like &lt;code&gt;Box&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; work by either manually implementing a memory allocator with the &lt;code&gt;GlobalAlloc&lt;/code&gt; trait or using the system allocator (which is usually the one dictated by the standard C library). Without &lt;code&gt;alloc&lt;/code&gt;, collections, smart pointers, and dynamically-allocated strings &lt;code&gt;String&lt;/code&gt; in the standard library &lt;code&gt;std&lt;/code&gt; won't work.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;core&lt;/code&gt; library sits at the bottom of the Rust library pyramid and contains functionality that only depends on the Rust language itself and the hardware the Rust program is running on—meaning &lt;code&gt;core&lt;/code&gt; doesn't depend on anything else. &lt;code&gt;alloc&lt;/code&gt; sits on top of &lt;code&gt;core&lt;/code&gt; in the Rust library hierarchy. So you can begin to see the order of library dependency:&lt;br&gt;
&lt;code&gt;std -[depends on]-&amp;gt; alloc -[depends on]-&amp;gt; core&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When we use the crate attribute &lt;code&gt;#![no_std]&lt;/code&gt;, we are saying we want to change default action of Rust to instead remove access to &lt;code&gt;std&lt;/code&gt; and &lt;code&gt;alloc&lt;/code&gt; and only keep &lt;code&gt;core&lt;/code&gt;. This ensures &lt;code&gt;std&lt;/code&gt; is not compiled with source code and changes the Rust library prelude from &lt;code&gt;std::prelude&lt;/code&gt; to &lt;code&gt;core::prelude&lt;/code&gt;. This doesn't mean you can't access &lt;code&gt;std&lt;/code&gt; in a &lt;code&gt;#![no_std]&lt;/code&gt; environment, you still can using &lt;code&gt;extern crate std&lt;/code&gt; but accessing &lt;code&gt;std&lt;/code&gt; will have to be explicit and dependent on if the target platform (i.e. the environment where your Rust code will run) allows &lt;code&gt;std&lt;/code&gt;. The same rule applies for &lt;code&gt;alloc&lt;/code&gt; in the sense that Rust allows you the ability to dynamically allocate memory in a &lt;code&gt;#![no_std]&lt;/code&gt; environment, that said, this action also has to be explicit and is dependent on two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;you manually implementing a memory allocator if the target platform does not have one,&lt;/li&gt;
&lt;li&gt;if the target platform allows implementation of a system allocator. A couple things might hinder this, one example is if there's too little memory to permit dynamic memory allocation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now you see, in embedded environments (i.e. microcontrollers and SoCs) where limitations on compute and memory are prevalent we must make do with data stored on the stack and static memory. We cannot use the heap memory because in such environments we lack memory allocation. That means bye-bye to flexible data structures like &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt;. Looking at what we have available by default in Rust &lt;code&gt;core&lt;/code&gt;, the closest stack data structure akin to &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; is the &lt;code&gt;core::array&lt;/code&gt; (aka. array) primitive type, typed in code as &lt;code&gt;[T; N]&lt;/code&gt;. But we know the limitations of &lt;code&gt;array&lt;/code&gt; compared to &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt;, for example;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;array&lt;/code&gt; must be fixed-sized to &lt;code&gt;N&lt;/code&gt;, &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; is variably-sized,&lt;/li&gt;
&lt;li&gt;denoting an array as &lt;code&gt;[T; N]&lt;/code&gt; means &lt;code&gt;T&lt;/code&gt; must be &lt;code&gt;Copy&lt;/code&gt; (shorthand lingo for &lt;code&gt;T&lt;/code&gt; must implement the &lt;code&gt;Copy&lt;/code&gt; trait),&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;array&lt;/code&gt; creates a fixed-size contiguous space where each space is data stored in the stack memory, while &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; allocates memory in the heap and returns a pointer (off on a tangent here: understanding the difference between a value, variable, and pointer in Rust greatly contributes to improving your understanding of pointers),&lt;/li&gt;
&lt;li&gt;plus a couple more differences that are not important to our use case otherwise would mention where applicable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Despite these differences and limitations between &lt;code&gt;array&lt;/code&gt; and &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt;, as the more similar data structures, it'd be nice to be able be create a &lt;code&gt;Vec&lt;/code&gt;-like data structure that fundamentally functions like an array (therefore, without needing heap allocation) but inherits (not to be confused with OOP Inheritance as Rust doesn't do that) some functionality of &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt;—a &lt;em&gt;heapless vector&lt;/em&gt; data structure. That's what we'll build next.&lt;/p&gt;
&lt;h2&gt;
  
  
  Building a Heapless Vector Type
&lt;/h2&gt;

&lt;p&gt;Now you understand &lt;em&gt;the what&lt;/em&gt; and &lt;em&gt;the why&lt;/em&gt;, let's talk about &lt;em&gt;the how&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To build a &lt;em&gt;heapless vector&lt;/em&gt; you must allocate enough memory upfront (in the form of the &lt;code&gt;N&lt;/code&gt; size of elements in a &lt;code&gt;[T; N]&lt;/code&gt; array)—either in static memory or in a function stack frame—for the largest number of elements you expect the vector to be able to hold, and then augment it with a &lt;code&gt;usize&lt;/code&gt; that tracks how many elements it currently holds. To push to the vector, you write to the next element in the (statically sized) array and increment a variable that tracks the number of elements. If the vector's length ever reaches the static size, the next push fails.&lt;/p&gt;

&lt;p&gt;First, we'll do this using &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; to depict allocating memory upfront using safe Rust with a minimal performance overhead compared to the next option (as time-space complexity is dependent on &lt;code&gt;N&lt;/code&gt; elements). Then, using &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; with uninitialized memory, using unsafe Rust, with better performance. In both cases, we'll work with &lt;code&gt;const&lt;/code&gt; generics. Finally, let's dig into some code.&lt;/p&gt;
&lt;h3&gt;
  
  
  Using &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Debug)]&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;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&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;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Copy&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&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;N&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&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;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Copy&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;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ArrayVec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;values&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="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;T&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;if&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&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;t&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&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="nf"&gt;Ok&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;&lt;code&gt;ArrayVec&lt;/code&gt; is generic over both the type of its elements, &lt;code&gt;T&lt;/code&gt;, and the maximum number of elements, &lt;code&gt;N&lt;/code&gt;. &lt;code&gt;ArrayVec&lt;/code&gt; is represented as an array of &lt;code&gt;N&lt;/code&gt; optional &lt;code&gt;T&lt;/code&gt;s. With &lt;code&gt;ArrayVec&lt;/code&gt; generic over &lt;code&gt;const N: usize&lt;/code&gt;, &lt;code&gt;N&lt;/code&gt;, must be known at compile time allowing the vector to be stored on the stack while using runtime information to manage how we access the array.&lt;/p&gt;

&lt;p&gt;Testing &lt;code&gt;ArrayVec&lt;/code&gt; with some code, we can see how it works and how to interact with it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;SIZE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&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;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;arr_vec1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ArrayVec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SIZE&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;new&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;arr_vec1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// view ArrayVec after init&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;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;SIZE&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;arr_vec1&lt;/span&gt;&lt;span class="nf"&gt;.try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&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="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;arr_vec1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// view ArrayVec after pushing elements&lt;/span&gt;

    &lt;span class="c1"&gt;// Pushing elements beyond ArrayVec len; should return Err&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr_vec1&lt;/span&gt;&lt;span class="nf"&gt;.try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&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="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;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// arr_vec does not change&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;arr_vec1&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;Running the code above returns:&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;# Stdout:&lt;/span&gt;
ArrayVec &lt;span class="o"&gt;{&lt;/span&gt; values: &lt;span class="o"&gt;[&lt;/span&gt;None, None, None, None, None], len: 0 &lt;span class="o"&gt;}&lt;/span&gt;
ArrayVec &lt;span class="o"&gt;{&lt;/span&gt; values: &lt;span class="o"&gt;[&lt;/span&gt;Some&lt;span class="o"&gt;(&lt;/span&gt;10&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;11&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;12&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;13&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;14&lt;span class="o"&gt;)]&lt;/span&gt;, len: 5 &lt;span class="o"&gt;}&lt;/span&gt;
Err&lt;span class="o"&gt;(&lt;/span&gt;15&lt;span class="o"&gt;)&lt;/span&gt;
ArrayVec &lt;span class="o"&gt;{&lt;/span&gt; values: &lt;span class="o"&gt;[&lt;/span&gt;Some&lt;span class="o"&gt;(&lt;/span&gt;10&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;11&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;12&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;13&lt;span class="o"&gt;)&lt;/span&gt;, Some&lt;span class="o"&gt;(&lt;/span&gt;14&lt;span class="o"&gt;)]&lt;/span&gt;, len: 5 &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Notice in our code, we haven't added the &lt;code&gt;#![no_std]&lt;/code&gt; crate attribute yet. We will do that in the next section on  &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can see that &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; works as the optional type that holds a valid value when we have successfully pushed a value, &lt;code&gt;T&lt;/code&gt;, and &lt;code&gt;None&lt;/code&gt; when we haven't. So what is the performance overhead caused by &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; here?&lt;/p&gt;

&lt;p&gt;Working in a limited environment like that of embedded systems, we really want to be conservative with our use of storage (if any) and memory space. That means storing &lt;code&gt;None&lt;/code&gt; in, for example, an array of &lt;code&gt;1_000_000&lt;/code&gt; &lt;code&gt;N&lt;/code&gt; values, where each &lt;code&gt;None&lt;/code&gt; is byte-aligned to the size of &lt;code&gt;T&lt;/code&gt; if &lt;code&gt;T&lt;/code&gt; does not allow &lt;em&gt;niche optimization&lt;/em&gt; for &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt;, is wasteful compared to the alternative and carries performance overhead for the array, and thus our &lt;code&gt;ArrayVec&lt;/code&gt; implementation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For brevity, I'm not going to talk about type alignment and layout in Rust but it goes a long way to help you comprehend, for example, what it means for "&lt;code&gt;None&lt;/code&gt; to be byte-aligned to the size of &lt;code&gt;T&lt;/code&gt;." Therefore, if you don't know about it I highly recommend you learn of it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Niche optimization is an optimization technique implemented by the Rust compiler &lt;code&gt;rustc&lt;/code&gt; on &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; if &lt;code&gt;T&lt;/code&gt; cannot be null or zeroed. It's a technique where the wrapper &lt;code&gt;Option&lt;/code&gt; type uses the same size as &lt;code&gt;T&lt;/code&gt; by assigning it's &lt;code&gt;None&lt;/code&gt; with the &lt;code&gt;0&lt;/code&gt; bit. That way if &lt;code&gt;T&lt;/code&gt; is 8 bytes, &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; will also be 8 bytes instead of 16 bytes.&lt;/p&gt;

&lt;p&gt;If the previous paragraphs were tough to understand, It might help to study type alignment and layout in Rust, as well as niche optimization by the Rust Compiler (&lt;code&gt;rustc&lt;/code&gt;) in more detail.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can experiment with the code of a &lt;strong&gt;heapless vector type&lt;/strong&gt; with &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; on the Rust playground via the link: &lt;a href="https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=a32ad95d9ad32d06d69bb7a612e57c4b" rel="noopener noreferrer"&gt;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=a32ad95d9ad32d06d69bb7a612e57c4b&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;You can also find the whole code on this GitHub Gist: &lt;a href="https://gist.github.com/allwelldotdev/10630be265c9548bfb0c591767afedf2" rel="noopener noreferrer"&gt;https://gist.github.com/allwelldotdev/10630be265c9548bfb0c591767afedf2&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's look at the more performant but unsafe alternative with &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; is a &lt;code&gt;union&lt;/code&gt; type, and &lt;code&gt;union&lt;/code&gt; types in Rust are rare and mostly used for interfacing with &lt;code&gt;C&lt;/code&gt; code through foreign function interfaces (FFI). Accessing the field of a &lt;code&gt;union&lt;/code&gt; in Rust is unsafe, therefore, we'll be introducing the use of unsafe code to implement &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What is the function of &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt;, how is it useful in the concept of building a heapless vector type?&lt;/p&gt;

&lt;h4&gt;
  
  
  What does &lt;em&gt;uninitialized&lt;/em&gt; mean?
&lt;/h4&gt;

&lt;p&gt;According to stdlib docs, &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; is a wrapper type to construct uninitialized instances of &lt;code&gt;T&lt;/code&gt;. What does "uninitialized" mean? I'll use the example of &lt;code&gt;let&lt;/code&gt; value-to-variable assignment to illustrate the meaning of initialized vs. uninitialized instances to help you &lt;em&gt;really&lt;/em&gt; understand what &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; does.&lt;/p&gt;

&lt;p&gt;Check out the code below.&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;init_var&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* `init_var` is a variable that holds a 32-bit signed
integer and is immediately initialized to the value of 10. */&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;uninit_var&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* In contrast, `uninit_var` is a variable that, at this point,
holds nothing (actually holds what are known as "garbage bytes" - invalid,
overwritable data in memory). Meaning, `uninit_var` points to *uninitialized*
memory.

At this point of the code, in safe code, Rust would *not* allow you use
`uninit_var` in any kind of computation that requires `uninit_var` to
be initialized. The compiler will complain that `uninit_var` is uninitialized
and using it would result in unexpected/undefined behaviour (UB). To use
`uninit_var`, we must initialize it with the appropriate value. */&lt;/span&gt;

&lt;span class="n"&gt;uninit_var&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* Finally, we initialize `uninit_var` with an 8-bit
unsigned integer of value 255. Rust's powerful type inference sets `uninit_var`
to be of type `u8`. If you try to assign `uninit_var` to a value of the wrong
type, the compiler will panic. */&lt;/span&gt;

&lt;span class="cm"&gt;/* Below is another example of Rust's type inference enforcing appropriate value
assignment. */&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;uninit_var&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* Variable holds no value and points to unitialized memory of
type 8-bit signed integer. */&lt;/span&gt;
&lt;span class="n"&gt;uninit_var&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* ❌ ERROR: You must initialize `uninit_var` with the
appropriate value. `i8::MAX` is 127. */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Therefore, in a nutshell, uninitialized memory are regions that haven't been filled with valid data yet. Accessing uninitialized memory through normal types like &lt;code&gt;i32&lt;/code&gt; or &lt;code&gt;String&lt;/code&gt; leads to UB because the compiler assumes all values are properly initialized (e.g., references are not null, &lt;code&gt;bool&lt;/code&gt;s are &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;, and padding bytes in structs are not garbage).&lt;/p&gt;

&lt;p&gt;Here's another a more elaborate definition: &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; lets you represent potentially uninitialized data without immediate UB. It's a &lt;code&gt;union&lt;/code&gt; type with &lt;code&gt;#[repr(transparent)]&lt;/code&gt;, meaning it has the &lt;em&gt;exact same size, alignment, and application binary interface (ABI)&lt;/em&gt; as T—no overhead. Unlike &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt;, it doesn't track initialization at runtime (no discriminant), so you must manually ensure safety via invariants (promises you make in unsafe code). Dropping a &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; never calls &lt;code&gt;T&lt;/code&gt;'s destructor; that's your job if it's initialized.&lt;/p&gt;

&lt;p&gt;According to stdlib docs, "&lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; serves to enable unsafe code to deal with uninitialized data. It is a signal to the compiler &lt;strong&gt;indicating that the data here might &lt;em&gt;not&lt;/em&gt; be initialized&lt;/strong&gt;. The compiler then knows to not make any incorrect assumptions or optimizations on this code. You can think of &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; as being a bit like &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; but without any of the run-time tracking and without any of the safety checks."&lt;br&gt;
Learn more about &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; from the &lt;a href="https://doc.rust-lang.org/std/mem/union.MaybeUninit.html" rel="noopener noreferrer"&gt;stdlib docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Having understood what &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; is, let's see it's function in building a heapless vector type.&lt;/p&gt;

&lt;p&gt;Rewriting the earlier implementation of &lt;code&gt;ArrayVec&lt;/code&gt; from &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; to &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt;:&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;#![no_std]&lt;/span&gt; &lt;span class="c1"&gt;// Explicity stating this crate does not use `std`&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;arrayvec&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;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;MaybeUninit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;#[derive(Debug)]&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;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&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;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MaybeUninit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&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;N&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="cd"&gt;/// Creates a new empty ArrayVec with an array of uninitialized `T`&lt;/span&gt;
        &lt;span class="cd"&gt;/// and `len` = 0.&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;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ArrayVec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// values: unsafe { MaybeUninit::uninit().assume_init() },&lt;/span&gt;
                &lt;span class="c1"&gt;// Below is same as the commented code above but safer.&lt;/span&gt;
                &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nn"&gt;MaybeUninit&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;uninit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="cd"&gt;/// Pushes `T` if all `N` elements have not been initialized;&lt;/span&gt;
        &lt;span class="cd"&gt;/// else returns `Err(T)`.&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;try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;T&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;if&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&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;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&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="nf"&gt;Ok&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;First, notice the newly added crate attribute &lt;code&gt;#![no_std]&lt;/code&gt; that signifies the code is built for an environment without support for the Rust standard library. Next, we move &lt;code&gt;ArrayVec&lt;/code&gt; and its implementations into a &lt;code&gt;mod&lt;/code&gt; to mimic an organized project structure and visibility. &lt;code&gt;values&lt;/code&gt; is now an array of &lt;code&gt;N&lt;/code&gt; maybe uninitialized values &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt;. &lt;code&gt;len&lt;/code&gt; continues to track the number of initialized elements.&lt;/p&gt;

&lt;p&gt;Following similar implementations on &lt;code&gt;ArrayVec&lt;/code&gt; with &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt;, now with &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;new&lt;/code&gt; introduces allocation to static memory with &lt;code&gt;const&lt;/code&gt; and the &lt;code&gt;MaybeUninit::uninit()&lt;/code&gt; associated function to return an array of uninitialized instances of &lt;code&gt;T&lt;/code&gt; to the &lt;code&gt;values&lt;/code&gt; field. In place of the safe variant we could also use the unsafe variant with &lt;code&gt;.assume_init()&lt;/code&gt; on &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; to create and assign an array of &lt;code&gt;N&lt;/code&gt; uninitialized instances of &lt;code&gt;T&lt;/code&gt; to the &lt;code&gt;values&lt;/code&gt; field, as seen in the commented code, because it returns the same value. Let me explain.

&lt;ul&gt;
&lt;li&gt;When you declare a field like &lt;code&gt;values: [MaybeUninit&amp;lt;T&amp;gt;; N]&lt;/code&gt; in a struct, Rust doesn't require (or perform) any explicit initialization of the array's contents to a "valid" state for &lt;code&gt;T&lt;/code&gt; at construction time. Instead the array starts in a raw, uninitialized memory state (i.e., whatever &lt;strong&gt;garbage bytes&lt;/strong&gt; happen to be on the stack at that moment), and the &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; wrapper semantically interprets those bytes as "uninitialized" without any runtime cost or safety violation. Hence the reason I used the safe variant instead and commented the unsafe variant. Meaning the unsafe variant was safe to use in that context anyway but I chose to go with safe Rust. Other places where I use &lt;code&gt;unsafe&lt;/code&gt;, I document (i.e. comment) the safety invariants that make using the &lt;code&gt;unsafe&lt;/code&gt; code safe.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;try_push&lt;/code&gt; acts like &lt;code&gt;.push&lt;/code&gt; on &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt;, takes in and writes &lt;code&gt;T&lt;/code&gt; directly to uninitialized memory in the array (if all &lt;code&gt;N&lt;/code&gt; elements have not been initialized, otherwise returns &lt;code&gt;Err(T)&lt;/code&gt;) and increments &lt;code&gt;len&lt;/code&gt; to track number of initialized elements.&lt;/li&gt;

&lt;/ul&gt;

&lt;h4&gt;
  
  
  Add &lt;code&gt;get&lt;/code&gt; and &lt;code&gt;pop&lt;/code&gt; Methods
&lt;/h4&gt;

&lt;p&gt;In full vector style, let's add more useful methods to &lt;code&gt;ArrayVec&lt;/code&gt; like &lt;code&gt;get&lt;/code&gt;, &lt;code&gt;pop&lt;/code&gt;, and a getter &lt;code&gt;len&lt;/code&gt;.&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;// ...earlier code.&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...earlier code.&lt;/span&gt;

    &lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&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;// ...earlier code.&lt;/span&gt;

        &lt;span class="cd"&gt;/// Returns a reference to the element at `index` if within bounds&lt;/span&gt;
        &lt;span class="cd"&gt;/// and initialized; else returns `None`.&lt;/span&gt;
        &lt;span class="cd"&gt;///&lt;/span&gt;
        &lt;span class="cd"&gt;/// SAFETY: Unsafe internally: Assumes the first `len` slots are&lt;/span&gt;
        &lt;span class="cd"&gt;/// initialized.&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;T&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;if&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;unsafe&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="o"&gt;&amp;amp;*&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.as_ptr&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="cd"&gt;/// Pops the last value, if any, returning owned `T` (or `None`&lt;/span&gt;
        &lt;span class="cd"&gt;/// if empty).&lt;/span&gt;
        &lt;span class="cd"&gt;///&lt;/span&gt;
        &lt;span class="cd"&gt;/// SAFETY: Uses `.assume_init_read()` to extract (read) and mark&lt;/span&gt;
        &lt;span class="cd"&gt;/// memory as uninitialized (this is also helped by the&lt;/span&gt;
        &lt;span class="cd"&gt;/// decrementing of `self.len` for the next `try_push`).&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;pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&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;if&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&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="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.assume_init_read&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="cd"&gt;/// Getter for current length.&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;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&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;While implementing &lt;code&gt;get&lt;/code&gt; and &lt;code&gt;pop&lt;/code&gt; methods on &lt;code&gt;ArrayVec&lt;/code&gt;, we use &lt;code&gt;unsafe&lt;/code&gt; and document safety invariants (i.e. guarantees) that describe safety rules we upheld to ensure a safe implementation of unsafe code, and we introduced methods like &lt;code&gt;.as_ptr()&lt;/code&gt; and &lt;code&gt;.assume_init_read()&lt;/code&gt; that allow us to reach into the &lt;em&gt;initialized instances&lt;/em&gt; of &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; and perform computation on them.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;get&lt;/code&gt; we take in an index value that points to the array data we want to get. Before we perform the get operation on the &lt;code&gt;values&lt;/code&gt; array we ensure we're only getting initialized indexed values by using the &lt;code&gt;if&lt;/code&gt; statement to return &lt;code&gt;None&lt;/code&gt; otherwise. After returning an initialized indexed value from the &lt;code&gt;values&lt;/code&gt; array, we obtain it's immutable raw pointer using &lt;code&gt;.as_ptr()&lt;/code&gt;, dereference the raw pointer to access its value using &lt;code&gt;*&lt;/code&gt; (this action requires &lt;code&gt;unsafe&lt;/code&gt;), then return a shared reference &lt;code&gt;&amp;amp;&lt;/code&gt; of the value in the &lt;code&gt;Some&lt;/code&gt; variant.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pop&lt;/code&gt; takes a mutable reference of &lt;code&gt;self&lt;/code&gt; because it mutates &lt;code&gt;self.len&lt;/code&gt;, checks before popping if the array is empty (returns &lt;code&gt;None&lt;/code&gt; if empty), and decrements &lt;code&gt;self.len&lt;/code&gt; to track the un-initialization of formerly initialized memory caused by the &lt;code&gt;.assume_init_read()&lt;/code&gt; method call on &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt;. &lt;code&gt;.assume_init_read()&lt;/code&gt; is an unsafe function that acts similar to &lt;code&gt;core::ptr::read&lt;/code&gt; or &lt;code&gt;std::ptr::read&lt;/code&gt; in that it performs a bitwise copy of &lt;code&gt;T&lt;/code&gt; whether &lt;code&gt;T&lt;/code&gt; is &lt;code&gt;Copy&lt;/code&gt; or not. This means if &lt;code&gt;T&lt;/code&gt; is not &lt;code&gt;Copy&lt;/code&gt; it moves &lt;code&gt;T&lt;/code&gt;. Such that if the memory location of &lt;code&gt;T&lt;/code&gt; is accessed after &lt;code&gt;.assume_init_read()&lt;/code&gt; was called on that same memory location, it will result in UB (similar to a use-after-free error). This is why &lt;code&gt;.assume_init_read()&lt;/code&gt; is perfect for an array pop operation on &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; values and returns owned &lt;code&gt;T&lt;/code&gt; in a &lt;code&gt;Some&lt;/code&gt; variant. To ensure the use of &lt;code&gt;unsafe&lt;/code&gt; code is safe, we first check the array is not empty guaranteeing it contains initialized instances of &lt;code&gt;T&lt;/code&gt; that we can call &lt;code&gt;.assume_init_read()&lt;/code&gt; on to extract &lt;code&gt;T&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Add Destructor
&lt;/h4&gt;

&lt;p&gt;Lastly, remember what I said earlier in the article when I described &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt;, I said, "dropping a &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; never calls &lt;code&gt;T&lt;/code&gt;'s destructor; that's your job if it's initialized." Using this knowledge, next, we implement &lt;code&gt;Drop&lt;/code&gt; for &lt;code&gt;ArrayVec&lt;/code&gt; to deallocate the &lt;code&gt;N&lt;/code&gt; initialized instances of &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; in the &lt;code&gt;values&lt;/code&gt; array.&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;// ...earlier code.&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...earlier code.&lt;/span&gt;

    &lt;span class="c1"&gt;// Implement Drop for ArrayVec to safely deallocate initialized elements.&lt;/span&gt;
    &lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Drop&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&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;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="cm"&gt;/* SAFETY: Explicitly drops the first `len` initialized elements.
            Therefore, no double frees. */&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.values&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;.assume_init_drop&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="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;We implement a destructor for &lt;code&gt;ArrayVec&lt;/code&gt; that the compiler calls to drop (i.e. free or deallocate) &lt;code&gt;ArrayVec&lt;/code&gt; when it goes out of scope.&lt;/p&gt;

&lt;p&gt;Inside the &lt;code&gt;drop&lt;/code&gt; function, we iterate through the &lt;code&gt;self.values&lt;/code&gt; array and call &lt;code&gt;.assume_init_drop()&lt;/code&gt; on each &lt;em&gt;initialized instance&lt;/em&gt; of &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; which drops the contained value &lt;code&gt;T&lt;/code&gt; in place. The safety invariant satisfied here is we explicitly drop only the first &lt;code&gt;self.len&lt;/code&gt; initialized elements, we don't touch the uninitialized &lt;code&gt;T&lt;/code&gt;. Because calling &lt;code&gt;.assume_init_drop()&lt;/code&gt; when &lt;code&gt;T&lt;/code&gt; is not yet fully initialized causes UB.&lt;/p&gt;

&lt;h4&gt;
  
  
  Converting to a &lt;code&gt;slice&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;We've come quite far already but there's just a little more to do to enable us debug the values pushed into &lt;code&gt;ArrayVec&lt;/code&gt;. If we try to use &lt;code&gt;ArrayVec&lt;/code&gt; as it is in this moment, we'll receive an incoherent output. To help your understanding, here's a code example:&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;#![no_std]&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="k"&gt;crate&lt;/span&gt; &lt;span class="n"&gt;std&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;arrayvec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ArrayVec&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;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ...`ArrayVec` implementation. */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;CAP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&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;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create ArrayVec with 16-bit unsigned integer and array of `CAP` size.&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;arr_vec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ArrayVec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CAP&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;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;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Iterate and push values into ArrayVec.&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CAP&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&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;// Print ArrayVec to stdout for debugging.&lt;/span&gt;
    &lt;span class="nn"&gt;std&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;arr_vec&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;If I ran this code with &lt;code&gt;cargo run&lt;/code&gt; I'd get the following output:&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;# Stdout:&lt;/span&gt;
ArrayVec &lt;span class="o"&gt;{&lt;/span&gt; values: &lt;span class="o"&gt;[&lt;/span&gt;MaybeUninit&amp;lt;u16&amp;gt;, MaybeUninit&amp;lt;u16&amp;gt;, MaybeUninit&amp;lt;u16&amp;gt;, MaybeUninit&amp;lt;u16&amp;gt;, MaybeUninit&amp;lt;u16&amp;gt;], len: 3 &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how the size of the array is &lt;code&gt;5&lt;/code&gt; yet the number of initialized elements is &lt;code&gt;3&lt;/code&gt; (tracked by the &lt;code&gt;len&lt;/code&gt; field of &lt;code&gt;ArrayVec&lt;/code&gt;), and we cannot see the values pushed into the array instead we see &lt;code&gt;MaybeUninit&amp;lt;u16&amp;gt;&lt;/code&gt;. That is precisely the reason why we need to be able to convert &lt;code&gt;ArrayVec&lt;/code&gt; to a &lt;code&gt;slice&lt;/code&gt; so we can peep into it's initialized values and debug what was inserted or computed in there.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What's a &lt;code&gt;slice&lt;/code&gt;? A &lt;code&gt;slice&lt;/code&gt; is a primitive type in Rust that is a &lt;em&gt;dynamically-sized&lt;/em&gt; view into a contiguous sequence, denoted by &lt;code&gt;[T]&lt;/code&gt;. Yes a slice is dynamically-sized though that has nothing to do with heap allocation. A slice is dynamically-sized because a slice is a fat (or wide) pointer that holds information about a location in memory and a length. In other words, a slice is a view into a block of memory represented as a pointer and a length. Learn more about &lt;code&gt;slice&lt;/code&gt;s in Rust via the &lt;a href="https://doc.rust-lang.org/std/primitive.slice.html" rel="noopener noreferrer"&gt;stdlib docs&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Using a &lt;code&gt;slice&lt;/code&gt;, we can take a view into &lt;code&gt;ArrayVec&lt;/code&gt; for its initialized elements. To do that, we implement methods on &lt;code&gt;ArrayVec&lt;/code&gt; that allow us convert it into a slice.&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;// ...earlier code.&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...earlier code.&lt;/span&gt;

    &lt;span class="c1"&gt;// Add methods to convert ArrayVec into a slice.&lt;/span&gt;
    &lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N&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;// ...earlier code.&lt;/span&gt;

        &lt;span class="cd"&gt;/// Return a slice using `slice::from_raw_parts()`. Returns a slice&lt;/span&gt;
        &lt;span class="cd"&gt;/// over initialized elements (i.e. first `self.len` slots).&lt;/span&gt;
        &lt;span class="cd"&gt;///&lt;/span&gt;
        &lt;span class="cd"&gt;/// SAFETY: Unsafe internally, but safe API: assumes invariant holds.&lt;/span&gt;
        &lt;span class="cd"&gt;/// Length points to valid length of init elements.&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;as_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_raw_parts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.values&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;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;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&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="cd"&gt;/// Returns a mutable slice over initialized elements.&lt;/span&gt;
        &lt;span class="cd"&gt;///&lt;/span&gt;
        &lt;span class="cd"&gt;/// SAFETY: Length param is valid length of init elements.&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;as_mut_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;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="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_raw_parts_mut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.values&lt;/span&gt;&lt;span class="nf"&gt;.as_mut_ptr&lt;/span&gt;&lt;span class="p"&gt;()&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;mut&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.len&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;core::slice::from_raw_parts()&lt;/code&gt; and &lt;code&gt;core::slice::from_raw_parts_mut()&lt;/code&gt; are unsafe functions therefore you must call them inside &lt;code&gt;unsafe&lt;/code&gt; blocks. Both take in a raw pointer (immutable and mutable respectively) and the length of the slice which corresponds, in our case, to the length of initialized elements which we track with &lt;code&gt;self.len&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Modifying the &lt;code&gt;main()&lt;/code&gt; function from before slightly (as seen below) we'll be able to debug the values pushed in.&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;// ...earlier code.&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* ...earlier code.
    After creating ArrayVec and pushing values into it.
    See similar earlier code for this missing section. */&lt;/span&gt;

    &lt;span class="c1"&gt;// Repeat initial ArrayVec print.&lt;/span&gt;
    &lt;span class="nn"&gt;std&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;arr_vec&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Print ArrayVec *now as slice* to stdout for debugging.&lt;/span&gt;
    &lt;span class="nn"&gt;std&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="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Init values: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.as_slice&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;Returns:&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;# Stdout:&lt;/span&gt;
ArrayVec &lt;span class="o"&gt;{&lt;/span&gt; values: &lt;span class="o"&gt;[&lt;/span&gt;MaybeUninit&amp;lt;u16&amp;gt;, MaybeUninit&amp;lt;u16&amp;gt;, MaybeUninit&amp;lt;u16&amp;gt;, MaybeUninit&amp;lt;u16&amp;gt;, MaybeUninit&amp;lt;u16&amp;gt;], len: 3 &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;---&lt;/span&gt;
Init values: &lt;span class="o"&gt;[&lt;/span&gt;10, 11, 12]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, now we can properly debug values pushed or computed in &lt;code&gt;ArrayVec&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's conclude with a couple final tests on &lt;code&gt;ArrayVec&lt;/code&gt; to showcase its function.&lt;/p&gt;

&lt;h4&gt;
  
  
  Testing
&lt;/h4&gt;

&lt;p&gt;Let's test our heapless vector type altogether now.&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;#![no_std]&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="k"&gt;crate&lt;/span&gt; &lt;span class="n"&gt;std&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;arrayvec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ArrayVec&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;arrayvec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ...`ArrayVec` implementation. */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;CAP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&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;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;ArrayVec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CAP&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;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nn"&gt;std&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;arr_vec&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// View init ArrayVec&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;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Push a few elements&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CAP&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&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="nn"&gt;std&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;arr_vec&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// View pushed elements&lt;/span&gt;

    &lt;span class="c1"&gt;// Return elements in initialized index.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;arr_els&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.as_slice&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nn"&gt;std&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="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Init values: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arr_els&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Pop from MaybeUninit ArrayVec; if uninit, return None.&lt;/span&gt;
    &lt;span class="nn"&gt;std&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="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;ArrayVec `len` before pop: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="nn"&gt;std&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;"Popped value: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.pop&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="nn"&gt;std&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;"ArrayVec `len` after pop: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="c1"&gt;// TEST: Add more elements beyond `CAP` size for ArrayVec;&lt;/span&gt;
    &lt;span class="c1"&gt;// `try_push` should escape and return with Err.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;arr_len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;arr_vec&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;arr_len&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="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="cm"&gt;/* I can deref the pointer
    for the value here without moving the value because I know it's a
    primitive value which enables bitwise copy. */&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;arr_err_els&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ArrayVec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nb"&gt;i32&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;CAP&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="nn"&gt;ArrayVec&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;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;arr_len&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CAP&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;count&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="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;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.try_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;arr_err_els&lt;/span&gt;&lt;span class="nf"&gt;.try_push&lt;/span&gt;&lt;span class="p"&gt;(&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;value&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="p"&gt;}&lt;/span&gt;
    &lt;span class="nn"&gt;std&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="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Filled ArrayVec: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arr_vec&lt;/span&gt;&lt;span class="nf"&gt;.as_slice&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="nn"&gt;std&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;"Err beyond ArrayVec: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arr_err_els&lt;/span&gt;&lt;span class="nf"&gt;.as_slice&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;Returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ArrayVec &lt;span class="o"&gt;{&lt;/span&gt; values: &lt;span class="o"&gt;[&lt;/span&gt;MaybeUninit&amp;lt;i32&amp;gt;, MaybeUninit&amp;lt;i32&amp;gt;, MaybeUninit&amp;lt;i32&amp;gt;, MaybeUninit&amp;lt;i32&amp;gt;, MaybeUninit&amp;lt;i32&amp;gt;], len: 0 &lt;span class="o"&gt;}&lt;/span&gt;
ArrayVec &lt;span class="o"&gt;{&lt;/span&gt; values: &lt;span class="o"&gt;[&lt;/span&gt;MaybeUninit&amp;lt;i32&amp;gt;, MaybeUninit&amp;lt;i32&amp;gt;, MaybeUninit&amp;lt;i32&amp;gt;, MaybeUninit&amp;lt;i32&amp;gt;, MaybeUninit&amp;lt;i32&amp;gt;], len: 3 &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;---&lt;/span&gt;
Init values: &lt;span class="o"&gt;[&lt;/span&gt;1, 2, 3]
&lt;span class="nt"&gt;---&lt;/span&gt;
ArrayVec &lt;span class="sb"&gt;`&lt;/span&gt;len&lt;span class="sb"&gt;`&lt;/span&gt; before pop: 3
Popped value: Some&lt;span class="o"&gt;(&lt;/span&gt;3&lt;span class="o"&gt;)&lt;/span&gt;
ArrayVec &lt;span class="sb"&gt;`&lt;/span&gt;len&lt;span class="sb"&gt;`&lt;/span&gt; after pop: 2
&lt;span class="nt"&gt;---&lt;/span&gt;
Filled ArrayVec: &lt;span class="o"&gt;[&lt;/span&gt;1, 2, 3, 4, 5]
Err beyond ArrayVec: &lt;span class="o"&gt;[&lt;/span&gt;Err&lt;span class="o"&gt;(&lt;/span&gt;6&lt;span class="o"&gt;)&lt;/span&gt;, Err&lt;span class="o"&gt;(&lt;/span&gt;7&lt;span class="o"&gt;)&lt;/span&gt;, Err&lt;span class="o"&gt;(&lt;/span&gt;8&lt;span class="o"&gt;)&lt;/span&gt;, Err&lt;span class="o"&gt;(&lt;/span&gt;9&lt;span class="o"&gt;)&lt;/span&gt;, Err&lt;span class="o"&gt;(&lt;/span&gt;10&lt;span class="o"&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  In conclusion
&lt;/h2&gt;

&lt;p&gt;We've come a long way to learn how to build a heapless vector data structure using uninitialized values. From understanding how Rust models memory regions, to learning about how to configure Rust for unorthodox or constrained environments using the Rust without the Standard Library &lt;code&gt;#![no_std]&lt;/code&gt; practice, to building a heapless vector type &lt;code&gt;ArrayVec&lt;/code&gt; using &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt;, and then to optimizing &lt;code&gt;ArrayVec&lt;/code&gt; further by replacing &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; default values with &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; uninitialized values in the array.&lt;/p&gt;

&lt;p&gt;In optimizing &lt;code&gt;ArrayVec&lt;/code&gt; to &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; from &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt;, here are some of the advantages and tradeoffs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reduced memory footprint&lt;/strong&gt;. Exact &lt;code&gt;size_of::&amp;lt;T&amp;gt;()&lt;/code&gt; per element/index in array (no discriminant overhead); halves space for non-niche types like &lt;code&gt;i32&lt;/code&gt; (4 bytes vs. 8 bytes), cutting cache misses in large arrays.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Faster Access &amp;amp; No Branching&lt;/strong&gt;. Direct &lt;code&gt;ptr&lt;/code&gt; reads/writes via &lt;code&gt;unsafe { Some(&amp;amp;*self.values[index].as_ptr()) }&lt;/code&gt;; skips &lt;code&gt;Option&lt;/code&gt;'s runtime &lt;code&gt;is_some()&lt;/code&gt; checks. According to benchmark tests, this yields 1.5–2x speed in loops (e.g., 23ms vs. 62ms for 100M elements in an array).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Ergonomic&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simpler hot-path code&lt;/strong&gt;. Cleaner push/pop without enum wrapping/unwrapping.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Other&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Heapless/Embedded Fit&lt;/strong&gt;. Zero-cost abstraction for &lt;code&gt;#![no_std]&lt;/code&gt;; enables const init and SIMD-friendly uninit masking, ideal for real-time systems.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tradeoffs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Safety risk&lt;/strong&gt;. Introduces unsafe code; UB if invariants violated (e.g., reading uninit slots)—needs Miri testing vs. &lt;code&gt;Option&lt;/code&gt;'s compile-time guards.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ergonomic: More boilerplate.&lt;/strong&gt; Manual drops (with &lt;code&gt;assume_init_drop()&lt;/code&gt;) and init tracking (with &lt;code&gt;self.len&lt;/code&gt;); less intuitive for beginners than &lt;code&gt;Option&lt;/code&gt;'s automatic discriminant and destructor (&lt;code&gt;Drop&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance overhead&lt;/strong&gt;. Needing explicit lifetime management (with &lt;code&gt;impl&amp;lt;T, const N: usize&amp;gt; Drop for ArrayVec&amp;lt;T, N&amp;gt;&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This effort shows you can build sophisticated data structures using only the stack and static memory, omitting heap allocation. This kind of data structure is useful in embedded systems programming where heap allocation is often unavailable.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can experiment with the code of a &lt;strong&gt;heapless vector type&lt;/strong&gt; with &lt;code&gt;MaybeUninit&amp;lt;T&amp;gt;&lt;/code&gt; on the Rust playground via the link (PS. In the code file, you'll see I've added more features to &lt;code&gt;ArrayVec&lt;/code&gt; like the ability for iteration and so on): &lt;a href="https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=7b80863ed153627d1d86a6ee41a42167" rel="noopener noreferrer"&gt;https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2024&amp;amp;gist=7b80863ed153627d1d86a6ee41a42167&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;You can also find the whole code on this GitHub Gist: &lt;a href="https://gist.github.com/allwelldotdev/39c817ca8d40fe5aeb808eb6301a18ff" rel="noopener noreferrer"&gt;https://gist.github.com/allwelldotdev/39c817ca8d40fe5aeb808eb6301a18ff&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In another article, I'll extend this knowledge by sharing how to make &lt;code&gt;ArrayVec&lt;/code&gt; and its fundamental types (&lt;code&gt;&amp;amp;ArrayVec&lt;/code&gt; and &lt;code&gt;&amp;amp;mut ArrayVec&lt;/code&gt;) iterable (i.e. how to use &lt;code&gt;ArrayVec&lt;/code&gt; in a &lt;code&gt;for&lt;/code&gt; loop in Rust and more). Stay connected for that!&lt;/p&gt;




&lt;p&gt;👏🏾 Kudos for finishing the article.&lt;/p&gt;

&lt;p&gt;Hi there!  I'm Allwell, a passionate Rust developer currently working from Lagos, Nigeria. You can connect with me on X (&lt;a href="https://x.com/allwelldotdev/" rel="noopener noreferrer"&gt;&lt;code&gt;@allwelldotdev&lt;/code&gt;&lt;/a&gt;) or LinkedIn (&lt;a href="https://linkedin.com/in/allwelldotdev/" rel="noopener noreferrer"&gt;Allwell Agwu-Okoro&lt;/a&gt;). Let's build and learn Rust together.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>iot</category>
      <category>datastructures</category>
      <category>software</category>
    </item>
    <item>
      <title>How to Setup a GitHub SSH connection like a PRO.</title>
      <dc:creator>Allwell</dc:creator>
      <pubDate>Tue, 30 Apr 2024 07:59:18 +0000</pubDate>
      <link>https://dev.to/allwelldotdev/how-to-setup-a-github-ssh-connection-like-a-pro-2h6b</link>
      <guid>https://dev.to/allwelldotdev/how-to-setup-a-github-ssh-connection-like-a-pro-2h6b</guid>
      <description>&lt;p&gt;Discover a more secure and simpler way to push, pull, and clone repositories through GitHub to your local Git repo, or vice versa. The setup is not so simple, which is why many never do it. But once you learn to do it, implement, and use it overtime…you’ll never want to go back to passwords and passphrases.&lt;/p&gt;

&lt;h2&gt;
  
  
  A better understanding of SSH connections
&lt;/h2&gt;

&lt;p&gt;Hey, like you, for a while, I struggled to wrap my head around what SSH is and how it works. Until several practises, study, and courses; now I finally have a good understanding of the &lt;em&gt;Secure Shell&lt;/em&gt;, or SSH for short.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;SSH, or &lt;strong&gt;Secure Shell&lt;/strong&gt;, is a way to securely connect and operate a computer over a network, such as the internet. It lets you log in to another computer, execute commands, and transfer files, all while keeping the data safe from outsiders. Think of it as a secure and private conversation between two computers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s a much safer form of secure connection, than passwords. With passwords, hackers have the option of a brute-force hack where they enlist a software that uses probability techniques to guess at your correct password with numerous tries in seconds. With SSH connections, if the hacker doesn’t have access to your private key, there’s no chance or luck of a hack.&lt;/p&gt;

&lt;h2&gt;
  
  
  How an SSH connection works
&lt;/h2&gt;

&lt;p&gt;You &lt;em&gt;generate&lt;/em&gt; an SSH key-pair. Two keys; one is the public key, the other, the private key. These keys are encrypted, meaning they’re not designed to be readable or make much sense, they are &lt;em&gt;hashed&lt;/em&gt;. You can also call them hashes or encryption hashes.&lt;/p&gt;

&lt;p&gt;The private key stays in your local machine or account while the public key is transferred into the remote machine, server, or account, you want to access.&lt;/p&gt;

&lt;p&gt;To authenticate yourself, upon access, the private key is used to decrypt the public key which informs the remote machine, server, or account, that you’re the rightful owner or authorized user.&lt;/p&gt;

&lt;p&gt;Okay, enough with the theories, you came here for the how-to guide. Let’s get to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up a GitHub SSH connection
&lt;/h2&gt;

&lt;p&gt;GitHub offers multiple forms of secure connection. The default is password-protection. You’re probably using this one, if you’ve not tried to any other means of secure connection.&lt;/p&gt;

&lt;p&gt;Today, I’m gonna be sharing how you setup your own SSH connection to GitHub from your local machine. This article may favour Windows users more because I am a Windows user myself, though I’ll endeavour to spot the differences in practise for MacOS users as I spot them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 1: Check for generated key-pairs in your SSH directory.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check if you already have keys in your global SSH directory. You may already have keys on your local machine (or PC), check using the command below in your terminal (Git Bash, for Windows PCs).&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;ls&lt;/span&gt; &lt;span class="nt"&gt;-al&lt;/span&gt; ~/.ssh/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;STEP 2: Generate an SSH key-pair.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you find that you do have keys in your SSH directory and you’re certain those keys are for GitHub, then delete them (we’ll create new ones).&lt;/p&gt;

&lt;p&gt;If the keys in your SSH directory &lt;em&gt;are not&lt;/em&gt; for GitHub, we’ll create new ones for GitHub.&lt;/p&gt;

&lt;p&gt;If you &lt;em&gt;do not&lt;/em&gt; see any keys at all—FYI, keys look like these &lt;code&gt;id_rsa&lt;/code&gt; , &lt;code&gt;id_rsa.pub&lt;/code&gt; , &lt;code&gt;id_ed25519&lt;/code&gt; , &lt;code&gt;id_ed25519.pub&lt;/code&gt; —not a problem, we’ll create new ones for GitHub.&lt;/p&gt;

&lt;p&gt;Before we generate SSH key-pairs, there’re a few things to know and keep in mind.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Public keys are keys that are suffixed with ‘.pub’. Private keys are keys that &lt;em&gt;are not&lt;/em&gt; suffixed with anything, including ‘.pub’, in other words, private keys have no suffixes (sometimes this may vary, but if it does it’ll be explicitly specified). &lt;/li&gt;
&lt;li&gt;There are four common SSH key types by algorithm: Digital Signature Algorithm (DSA), Rivest-Shamir-Adleman (RSA), Elliptic curve based algorithms, and Ed25519. GitHub currently accepts three of these, namely; &lt;strong&gt;RSA&lt;/strong&gt;, &lt;strong&gt;ECDSA&lt;/strong&gt; and &lt;strong&gt;ED25519&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ED25519&lt;/strong&gt; is a modern public-key algorithm that offers better security than RSA and is faster in operation. RSA remains the most common and provides the broadest system compatibility.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Having this in mind, we’ll be creating an SSH key-pair using the RSA host key signature algorithm. Let’s begin. Type the command below into your terminal (Git Bash, for Windows PCs).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 4096 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"github your@email_address.com"&lt;/span&gt; &lt;span class="nt"&gt;-N&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"/c/Users/YourUsername/.ssh/id_rsa_github"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me break it down for you.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ssh-keygen&lt;/code&gt; : This command is used to generate, manage, and convert authentication keys for SSH.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-t rsa&lt;/code&gt; : Specifies the type of key to create, in this case, RSA.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-b 4096&lt;/code&gt; : Sets the key strength to 4096 bits, which is a good choice for security.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-C "github your@email_address.com"&lt;/code&gt; : Adds a comment to the key. It's useful for identifying the key's purpose or owner. Here, change the email to your GitHub email.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-N ""&lt;/code&gt; : This specifies an empty passphrase for the key, meaning the key will not require a passphrase to use. This is less secure but more convenient (we’ll come back to why I did this later in the article).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-f "/c/Users/YourUsername/.ssh/id_rsa_github"&lt;/code&gt; : Specifies the filename of the key file. This command saves the generated key to a file named id_rsa_github in your .ssh directory. This is useful if you have multiple SSH keys and want to keep them organized. Here, change ‘YourUsername’ to your PC username. We could have used a file path that look like this &lt;code&gt;-f "~/.ssh/id_rsa_github"&lt;/code&gt; but may likely throw an error that reads something like "Saving key '~/.ssh/id_rsa_github' failed: No such file or directory”. This is because the Shell does not recognize the file path. This is a common issue when using Git Bash on Windows, due to differences in how Unix-like systems and Windows handle file paths. Therefore you need to use an absolute path, which is the one I recommended in the command.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Running the command above in your terminal will generate two key-pairs and store them in your ‘.ssh’ directory. When you navigate to the ‘.ssh’ directory, you’ll see two keys &lt;code&gt;id_rsa_github.pub&lt;/code&gt; (public key), and &lt;code&gt;id_rsa_github&lt;/code&gt; (private key).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 3: Transfer your SSH public key to GitHub.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Copy the public key into the clipboard, because we’re about to paste it into our GitHub account to complete the process. Use the command below to do so.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;clip &amp;lt; ~/.ssh/id_rsa_github.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the public key is in the clipboard, log into your GitHub account, navigate to the &lt;a href="https://github.com/settings/keys" rel="noopener noreferrer"&gt;Settings&lt;/a&gt; page, click the ‘New SSH key’ button, insert/paste the public key into the textarea presented, give it a title, and save by clicking ‘Add SSH key’.&lt;/p&gt;

&lt;p&gt;Now, you’ve added your SSH public key into the GitHub servers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 4: Test your GitHub SSH connection.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Time to test your connection. Run the command below in your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; ~/.ssh/id_rsa_github &lt;span class="nt"&gt;-T&lt;/span&gt; git@github.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code runs a pseudo-terminal, hence the &lt;code&gt;-T&lt;/code&gt; flag, that tests your SSH connection authentication with GitHub servers.&lt;/p&gt;

&lt;p&gt;If you followed the steps correctly the command run should return something like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hi (yourGitHubUserName)! You’ve successfully authenticated, but GitHub does not provide shell access. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hurray! Your GitHub connection is complete, right? Not quite.&lt;/p&gt;

&lt;p&gt;Notice that when you run the same SSH connection test without specifying the path—using this flag &lt;code&gt;-i ~/.ssh/id_rsa_github&lt;/code&gt; — to your private key, it returns an error that reads like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="mailto:git@github.com"&gt;git@github.com&lt;/a&gt;: Permission denied (publickey) &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is because the SSH client isn't automatically finding your key because it's not named with one of the default expected filenames (like &lt;code&gt;id_rsa&lt;/code&gt;, &lt;code&gt;id_ecdsa&lt;/code&gt;, &lt;code&gt;id_ed25519&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;To make SSH automatically use your custom-named key—which we named as ‘id_rsa_github’—for GitHub, you have to set up an SSH configuration file to automatically apply specific settings for GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Doing it like a PRO
&lt;/h2&gt;

&lt;p&gt;So, you’re in the PRO game now. To ensure your SSH connection test works when you simply run the command &lt;code&gt;ssh -T git@github.com&lt;/code&gt; , you need to use an SSH config file, as stated in the previous paragraph. Here’s how to do it.&lt;/p&gt;

&lt;p&gt;Following from step 4 into…&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 5: Setup an SSH Config file.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a SSH config file using your favourite text editor (for me, I’ll use vscode). Type the command into the terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;code ~/.ssh/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following configuration to the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_rsa_github
    IdentitiesOnly &lt;span class="nb"&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;~/.ssh/id_rsa_github&lt;/code&gt; with the actual path to your SSH key (which may be the same path as the example if you followed through with everything I said to do, and did not make any personal changes to the filename).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;IdentitiesOnly yes&lt;/code&gt; ensures that only the specified key is used for the connection, which can speed up the connection process by not offering other keys.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Save and exit the file.&lt;/p&gt;

&lt;p&gt;Now, if you try to test your SSH connection again without specifying the path to the private key. Like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-T&lt;/span&gt; git@github.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should now work and return:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hi (yourGitHubUserName)! You’ve successfully authenticated, but GitHub does not provide shell access. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fantastic!&lt;/p&gt;

&lt;p&gt;My work here is done (in the voice of Thanos).&lt;/p&gt;

&lt;p&gt;And that’s how you setup a GitHub SSH connection like a PRO.&lt;/p&gt;

&lt;h2&gt;
  
  
  Alternatives to consider
&lt;/h2&gt;

&lt;p&gt;Notice, I didn’t ask you to set a passphrase when we generated an SSH key-pair? That was on purpose. If you’d added a passphrase to your SSH key-pair generation command—by adding content to the &lt;code&gt;-N&lt;/code&gt; flag, the process would be slightly different and more bogus, as you’ll have to work with an &lt;code&gt;ssh-agent&lt;/code&gt; command, as well as commands such as &lt;code&gt;eval&lt;/code&gt; and &lt;code&gt;ssh-add&lt;/code&gt; to make it work. Plus, the incessant prompting to input your passphrase into the terminal to decrypt your private key each time you want to SSH connect to GitHub. It gets tiring after a while and is not convenient.&lt;/p&gt;

&lt;p&gt;Soon, you’ll realize there’s little to no difference between a passphrase-enabled SSH connection and a password-protected connection to GitHub. That’s why I purposefully &lt;em&gt;did not&lt;/em&gt; set a passphrase for the key-pair we generated. This would ensure that your SSH connections to GitHub are always convenient and noninteractive.&lt;/p&gt;

&lt;p&gt;Essentially, this means, whenever you use the PC you setup a GitHub SSH connection on to push repos to, pull, and clone repos from GitHub, you’ll not be prompted to input any password or passphrase; the authentication will happen in the background. Which is how I and many other developers and engineers like it. I hope you’ll like it too.&lt;/p&gt;

&lt;p&gt;Enjoy.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

&lt;p&gt;Stay curious. Stay healthy.&lt;/p&gt;




&lt;p&gt;PS. I’ve published this article on &lt;a href="https://www.linkedin.com/pulse/how-setup-github-ssh-connection-like-pro-allwell-agwu-okoro-bczif/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; and &lt;a href="https://medium.com/@allwelldotdev/how-to-setup-a-github-ssh-connection-like-a-pro-38f10beaa082" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;. I’d like to ask you to, please give it a like and share so others may benefit from it too. Thank you again.&lt;/p&gt;

</description>
      <category>github</category>
      <category>ssh</category>
      <category>git</category>
    </item>
    <item>
      <title>I reduced to just 2 steps the deployment of a LAMP stack + Laravel app using Bash Shell Scripting, Vagrant, and Ansible.</title>
      <dc:creator>Allwell</dc:creator>
      <pubDate>Fri, 26 Apr 2024 16:48:26 +0000</pubDate>
      <link>https://dev.to/allwelldotdev/i-reduced-to-just-2-steps-the-deployment-of-a-lamp-stack-laravel-app-using-bash-shell-scripting-vagrant-and-ansible-24cl</link>
      <guid>https://dev.to/allwelldotdev/i-reduced-to-just-2-steps-the-deployment-of-a-lamp-stack-laravel-app-using-bash-shell-scripting-vagrant-and-ansible-24cl</guid>
      <description>&lt;p&gt;Hi there, Cloud and DevOps Enthusiasts, Engineers, and readers, my name is Allwell and I’m currently learning Cloud Computing &amp;amp; Engineering. With this article, I aim to share with you how I automated the deployment of a LAMP stack (Linux, Apache, MySQL, PHP) and Laravel app using bash shell scripting, Vagrant, and Ansible, down to just two simple steps.&lt;/p&gt;

&lt;p&gt;Automation can be defined as the simplification and streamlining of a process, where tasks that previously required multiple manual steps are configured to operate with minimal human intervention. This often involves using technology to execute tasks automatically, reducing the need for manual input to just a few or even a single step. The goal of automation is to increase efficiency, reduce errors, and free up human resources for more complex activities.&lt;/p&gt;

&lt;p&gt;At a bootcamp I’m attending known as AltSchool Africa (learning Cloud/DevOps Engineering), for second semester exams, I was tasked to do the following:&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Project Exam Summary:&lt;/strong&gt; Automatically provision multiple VMs (Virtual Machines) (2 - master &amp;amp; slave), create bash script to deploy LAMP Stack on master vm/node, use Ansible to execute the bash script on slave vm/node.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extended Project Exam Question:&lt;/strong&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Automate the provisioning of two Ubuntu-based servers, named “Master” and “Slave”, using Vagrant.&lt;/li&gt;
&lt;li&gt;On the Master node, create a bash script to automate the deployment of a LAMP stack (Linux, Apache, MySQL, PHP).

&lt;ol&gt;
&lt;li&gt;This script should clone a &lt;a href="https://github.com/laravel/laravel" rel="noopener noreferrer"&gt;Laravel PHP application from GitHub&lt;/a&gt;, install all necessary packages, and configure Apache web server and MySQL.&lt;/li&gt;
&lt;li&gt;Ensure the bash script is reusable and readable.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;Using an Ansible playbook:

&lt;ol&gt;
&lt;li&gt;Execute the bash script on the Slave node and verify that the PHP application is accessible through the VM’s IP address (take a screenshot of this as evidence).&lt;/li&gt;
&lt;li&gt;Create a cronjob to check the server’s uptime every 12 am.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;




&lt;h2&gt;
  
  
  Firing up my Virtual Machines (VMs)
&lt;/h2&gt;

&lt;p&gt;Solution: I created, or in engineering terms; fired up, two virtual machines (vm) using a vm automation tool known as Vagrant.&lt;/p&gt;

&lt;p&gt;Let’s call the host vm, &lt;strong&gt;Master&lt;/strong&gt;, and the server vm, &lt;strong&gt;Slave&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After initializing a Vagrant box (a Vagrant term for ‘an OS instance’), I wrote the init file - Vagrantfile, as seen below (my Vagrantfile config):&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="c1"&gt;# -*- mode: ruby -*-&lt;/span&gt;
&lt;span class="c1"&gt;# vi: set ft=ruby :&lt;/span&gt;

&lt;span class="no"&gt;Vagrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2"&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;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="c1"&gt;# configure general VM&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ubuntu/jammy64"&lt;/span&gt;

  &lt;span class="c1"&gt;# configure master vm&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt; &lt;span class="s2"&gt;"master"&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;master&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"master"&lt;/span&gt;
    &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"private_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="s2"&gt;"192.168.56.10"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# configure slave vm&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt; &lt;span class="s2"&gt;"slave"&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;slave&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;slave&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"slave"&lt;/span&gt;
    &lt;span class="n"&gt;slave&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"private_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="s2"&gt;"192.168.56.11"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt; 

  &lt;span class="c1"&gt;# provision both vms&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;inline: &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;SHELL&lt;/span&gt;&lt;span class="sh"&gt;

  # update system
  sudo apt-get update
&lt;/span&gt;&lt;span class="no"&gt;  SHELL&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;config.vm.box = "ubuntu/jammy64"&lt;/code&gt; This line states the operating system of the both vms is Ubuntu 22.04 LTS (Jammy Jellyfish).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;config.vm.define "master" do |master|&lt;/code&gt; &amp;amp; &lt;code&gt;config.vm.define "slave" do |slave|&lt;/code&gt; These lines tell Vagrant to fire up two virtual machines, one called master and the other slave.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;master.vm.network "private_network", ip: "192.168.56.10"&lt;/code&gt; &amp;amp; &lt;code&gt;slave.vm.network "private_network", ip: "192.168.56.11"&lt;/code&gt; These lines tell Vagrant to configure both vms with private static IPs so I can access them via a browser. The master vm is assigned the ip 192.168.56.10, while the slave vm is assigned the ip 192.168.56.11.&lt;/li&gt;
&lt;li&gt;There’s a huge part of the Vagrantfile code that is not visible yet, and that’s because the rest of the code is about provisioning for both vms, which I will talk about in detail later in this article. For now, let’s move on to writing the bash script to deploy a LAMP stack.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Bash Shell Script, or simply Bash Script.
&lt;/h2&gt;

&lt;p&gt;The bash script was the major hurdle in this task because it was the lifeblood that was required for the entire operation to run. The rest of the tasks were mostly automation scripts and software. Below, I break down the bash script into bits (as much I can).&lt;/p&gt;

&lt;p&gt;The task: Deploy a LAMP stack, clone the Laravel repo from GitHub, install all necessary packages, and configure the Apache web server, MySQL, and PHP.&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;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# Exit bash script upon any erors&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;

&lt;span class="c"&gt;# Define a function to run when an error occurs&lt;/span&gt;
error_handling&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"The script failed due to a fault"&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Error on line &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt; of bash script"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Trap any ERR signal and call error_handling function with the line number&lt;/span&gt;
&lt;span class="nb"&gt;trap&lt;/span&gt; &lt;span class="s1"&gt;'error_handling $LINENO'&lt;/span&gt; ERR

&lt;span class="c"&gt;# ----------------------------------------------------------&lt;/span&gt;

&lt;span class="c"&gt;# Source the 'deploy-LAMP-stack.cfg' configuration file&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Sourcing 'deploy-LAMP-stack.cfg' configuration file..."&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;2

&lt;span class="c"&gt;# Define path to the configuration file&lt;/span&gt;
&lt;span class="nv"&gt;CONFIG_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/deploy-LAMP-stack.cfg"&lt;/span&gt;

&lt;span class="c"&gt;# Check if the file exists, then source config file, or exit script&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CONFIG_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
    &lt;span class="c"&gt;# Source configuration file&lt;/span&gt;
    &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/deploy-LAMP-stack.cfg
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Configuration file loaded successfully..."&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="k"&gt;else
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Configuration file does not exist in user's home directory"&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Add configuration file 'deploy-LAMP-stack.cfg' to user's home directory - /home/user/"&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;1 &lt;span class="c"&gt;# Exit the script with an exit/return status of 1 indicating an error&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Ensure no interactive prompt during installation or while running script&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;DEBIAN_FRONTEND&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;noninteractive

&lt;span class="c"&gt;# Update Linux system package repo&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Updating and upgrading your system..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Apache2 Installation&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Installing Apache2..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;apache2  &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Enable mod_rewrite for Apache2&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;a2enmod rewrite

&lt;span class="c"&gt;# Adjust Firewall to Allow Web Traffic&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"Apache Full"&lt;/span&gt;

&lt;span class="c"&gt;# MySQL Installation&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Installing MySQL..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;mysql-server &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Secure MySQL Installation&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Securing SQL Installation"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;mysql_secure_installation &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;

y
n   
y
y
y
y
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# PHP Installation&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Installing PHP 8.2..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;add-apt-repository &lt;span class="nt"&gt;-y&lt;/span&gt; ppa:ondrej/php
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;php8.2 &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# PHP 8.2 Extensions Installation&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Installing required PHP 8.2 extensions..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;php8.2-cli php8.2-common php8.2-fpm php8.2-mysql php8.2-zip php8.2-gd php8.2-mbstring php8.2-curl php8.2-xml php8.2-bcmath php8.2-intl php8.2-zip libapache2-mod-php8.2 git unzip &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Restart Apache to load new config&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart apache2

&lt;span class="c"&gt;# Composer Installation&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Installing Composer..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;

curl &lt;span class="nt"&gt;-sS&lt;/span&gt; https://getcomposer.org/installer | &lt;span class="nb"&gt;sudo &lt;/span&gt;php &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--install-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/local/bin &lt;span class="nt"&gt;--filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;composer &lt;span class="nt"&gt;--quiet&lt;/span&gt;

&lt;span class="c"&gt;# Clone Laravel project from GitHub&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Cloning Laravel from GitHub..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; /var/www/html
&lt;span class="nb"&gt;sudo &lt;/span&gt;git clone https://github.com/laravel/laravel.git
&lt;span class="nb"&gt;cd &lt;/span&gt;laravel

&lt;span class="c"&gt;# Composer Dependencies Installation&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Installing Composer dependencies..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;composer &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-interaction&lt;/span&gt; &lt;span class="nt"&gt;--prefer-dist&lt;/span&gt; &lt;span class="nt"&gt;--optimize-autoloader&lt;/span&gt; &lt;span class="nt"&gt;--working-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/var/www/html/laravel

&lt;span class="c"&gt;# Setup MySQL Database&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Setting up MySQL database..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt;&lt;span class="nv"&gt;$DBPASS&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;MYSQL_SCRIPT&lt;/span&gt;&lt;span class="sh"&gt;
CREATE DATABASE &lt;/span&gt;&lt;span class="nv"&gt;$DBNAME&lt;/span&gt;&lt;span class="sh"&gt;;
CREATE USER '&lt;/span&gt;&lt;span class="nv"&gt;$DBUSER&lt;/span&gt;&lt;span class="sh"&gt;'@'localhost' IDENTIFIED BY '&lt;/span&gt;&lt;span class="nv"&gt;$DBPASS&lt;/span&gt;&lt;span class="sh"&gt;';
GRANT ALL PRIVILEGES ON &lt;/span&gt;&lt;span class="nv"&gt;$DBNAME&lt;/span&gt;&lt;span class="sh"&gt;.* TO '&lt;/span&gt;&lt;span class="nv"&gt;$DBUSER&lt;/span&gt;&lt;span class="sh"&gt;'@'localhost';
FLUSH PRIVILEGES;
&lt;/span&gt;&lt;span class="no"&gt;MYSQL_SCRIPT

&lt;/span&gt;&lt;span class="c"&gt;# Set permissions for Laravel storage and bootstrap cache directories&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Setting permissions for Laravel, storage and bootstrap cache directories..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; www-data:www-data /var/www/html/laravel
&lt;span class="nb"&gt;sudo chmod&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; 775 /var/www/html/laravel/storage /var/www/html/laravel/bootstrap/cache

&lt;span class="c"&gt;# Setup Laravel environment file&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Configuring Laravel environment..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo cp&lt;/span&gt; .env.example .env
&lt;span class="nb"&gt;sudo sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"s/DB_CONNECTION=sqlite/DB_CONNECTION=mysql/"&lt;/span&gt; .env
&lt;span class="nb"&gt;sudo sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s/^# DB_HOST=127.0.0.1/DB_HOST=127.0.0.1/'&lt;/span&gt; .env
&lt;span class="nb"&gt;sudo sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s/^# DB_PORT=3306/DB_PORT=3306/'&lt;/span&gt; .env
&lt;span class="nb"&gt;sudo sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"s/^# DB_DATABASE=laravel/DB_DATABASE=&lt;/span&gt;&lt;span class="nv"&gt;$DBNAME&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt; .env
&lt;span class="nb"&gt;sudo sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"s/^# DB_USERNAME=root/DB_USERNAME=&lt;/span&gt;&lt;span class="nv"&gt;$DBUSER&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt; .env
&lt;span class="nb"&gt;sudo sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"s/^# DB_PASSWORD=/DB_PASSWORD=&lt;/span&gt;&lt;span class="nv"&gt;$DBPASS&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt; .env
php artisan migrate

&lt;span class="c"&gt;# Clear and cache Laravel Artisan configurations&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Clearing and caching configurations..."&lt;/span&gt;
php artisan config:clear
php artisan cache:clear

&lt;span class="c"&gt;# Generate Laravel key&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Generating Laravel key..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;php artisan key:generate

&lt;span class="c"&gt;# Configure Apache to serve the Laravel project&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Configuring Apache to serve Laravel..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apache2/sites-available/laravel.conf &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
&amp;lt;VirtualHost *:80&amp;gt;
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html/laravel/public
    &amp;lt;Directory /var/www/html/laravel/public&amp;gt;
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Require all granted
    &amp;lt;/Directory&amp;gt;
    ErrorLog &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;APACHE_LOG_DIR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;/error.log
    CustomLog &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;APACHE_LOG_DIR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;/access.log combined
&amp;lt;/VirtualHost&amp;gt;
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Enable the Laravel site&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;a2ensite laravel.conf
&lt;span class="nb"&gt;sudo &lt;/span&gt;a2dissite 000-default.conf
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart apache2

&lt;span class="c"&gt;# LAMP stack + Laravel deployment: success&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"LAMP stack and Laravel are installed."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Script executed successfully."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s call the bash script “deploy-LAMP-stack.sh”.&lt;/p&gt;

&lt;p&gt;My goal for creating this script was to ensure it fully ran automatically, on its own, without any human input, prompt, or type interactions. I was thinking of a situation where I want to configure multiple vms at one go and want to fire them all up just by clicking the play button, and be certain about the safety and accuracy of the operation. This initiative forced me to make this bash script my own and tweak it beyond requirements to match my goal.&lt;/p&gt;

&lt;p&gt;Here’s how I achieved that.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To ensure the script is built to be reliable with zero interaction, I set the script to exit upon any errors and inserted an error handler function to catch the error line number, upon runtime, and display it to me so I can fix it in dev mode.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Exit bash script upon any erors&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;

&lt;span class="c"&gt;# Define a function to run when an error occurs&lt;/span&gt;
error_handling&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"The script failed due to a fault"&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Error on line &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt; of bash script"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Trap any ERR signal and call error_handling function with the line number&lt;/span&gt;
&lt;span class="nb"&gt;trap&lt;/span&gt; &lt;span class="s1"&gt;'error_handling $LINENO'&lt;/span&gt; ERR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Though, I didn’t want to, I concluded that I may have to create an external config file that contained the user-input variables required to run the script for things like setting up the MySQL database. Remember, I did this in the bid to ensure no interactivity in runtime but also ensure security of user input. Let’s call the external config file “deploy-LAMP-stack.cfg”.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Configuration file for 'deploy-LAMP-stack.sh' shell script
DBNAME="laravel_db"
DBUSER="laravel_user"
DBPASS="laravel_pass"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;I sourced the variables assigned in the external config file into the script and wrote an ‘if’ statement to check if the file exists then source the variables and run the script, otherwise, if the file does not exist, echo (or post) to runtime that the file does not exit and request it be inserted for script to run.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sleep 2&lt;/code&gt; I added this line to make it seem like the script was taking time (just 2 seconds) to search for the external config file. A touch of user experience there. Haha.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Source the 'deploy-LAMP-stack.cfg' configuration file&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Sourcing 'deploy-LAMP-stack.cfg' configuration file..."&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;2

&lt;span class="c"&gt;# Define path to the configuration file&lt;/span&gt;
&lt;span class="nv"&gt;CONFIG_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/deploy-LAMP-stack.cfg"&lt;/span&gt;

&lt;span class="c"&gt;# Check if the file exists, then source config file, or exit script&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CONFIG_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
    &lt;span class="c"&gt;# Source configuration file&lt;/span&gt;
    &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/deploy-LAMP-stack.cfg
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Configuration file loaded successfully..."&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="k"&gt;else
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Configuration file does not exist in user's home directory"&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Add configuration file 'deploy-LAMP-stack.cfg' to user's home directory - /home/user/"&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;1 &lt;span class="c"&gt;# Exit the script with an exit/return status of 1 indicating an error&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This line was another attempt to ensure the script runs non-interactively—no user prompts, no type prompts, no popups; just run.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Ensure no interactive prompt during installation or while running script&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;DEBIAN_FRONTEND&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;noninteractive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Then, the real fun begins. I start by updating my LinuxOS, which, remember, was set to Ubuntu 22.04 (Jammy Jellyfish) in the Vagrantfile. After which, I install and configure Apache2, MySQL, PHP, and PHP extensions. Mostly routine stuff.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Update Linux system package repo&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Updating and upgrading your system..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Apache2 Installation&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Installing Apache2..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;apache2  &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Enable mod_rewrite for Apache2&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;a2enmod rewrite

&lt;span class="c"&gt;# Adjust Firewall to Allow Web Traffic&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"Apache Full"&lt;/span&gt;

&lt;span class="c"&gt;# MySQL Installation&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Installing MySQL..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;mysql-server &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Secure MySQL Installation&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Securing SQL Installation"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;mysql_secure_installation &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;

y
n   
y
y
y
y
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# PHP Installation&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Installing PHP 8.2..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;add-apt-repository &lt;span class="nt"&gt;-y&lt;/span&gt; ppa:ondrej/php
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;php8.2 &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# PHP 8.2 Extensions Installation&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Installing required PHP 8.2 extensions..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;php8.2-cli php8.2-common php8.2-fpm php8.2-mysql php8.2-zip php8.2-gd php8.2-mbstring php8.2-curl php8.2-xml php8.2-bcmath php8.2-intl php8.2-zip libapache2-mod-php8.2 git unzip &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Restart Apache to load new config&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart apache2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Then, Composer. It took me almost a whole day to resolve Composer issues. It kept on bugging my script. I eventually figured it out and installed Composer appropriately. This flag &lt;code&gt;--install-dir=/usr/local/bin&lt;/code&gt; set the installation directory to an executable path. This ensures that running &lt;code&gt;composer&lt;/code&gt; as an executable command is possible. This flag &lt;code&gt;--filename=composer&lt;/code&gt; set the filename of the installed executable to ‘composer’. This flag &lt;code&gt;--quiet&lt;/code&gt; set the installation to run noninteractively.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Composer Installation&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Installing Composer..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;

curl &lt;span class="nt"&gt;-sS&lt;/span&gt; https://getcomposer.org/installer | &lt;span class="nb"&gt;sudo &lt;/span&gt;php &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--install-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/local/bin &lt;span class="nt"&gt;--filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;composer &lt;span class="nt"&gt;--quiet&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Cloned the Laravel app from GitHub.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone Laravel project from GitHub&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Cloning Laravel from GitHub..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; /var/www/html
&lt;span class="nb"&gt;sudo &lt;/span&gt;git clone https://github.com/laravel/laravel.git
&lt;span class="nb"&gt;cd &lt;/span&gt;laravel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Installed Composer dependencies for the Laravel app. The Composer installer looks at the directory where the Laravel app is installed and reads the &lt;code&gt;composer.json&lt;/code&gt; file to find dependency requirements for the app. Where it doesn’t see a dependency lock file (which locks the app dependencies to specifics for backwards compatibility and future proofing despite future updates to the Laravel app GitHub repo), that’s generally named a &lt;code&gt;composer.lock&lt;/code&gt; file, the Composer Installer installs dependency requirements stated in the &lt;code&gt;composer.json&lt;/code&gt; file (which are often latest dependency updates, which can in turn be troublesome for app reliability considering the bugs that are often found in latest, bleeding-edge, app updates).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Composer Dependencies Installation&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Installing Composer dependencies..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;composer &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-interaction&lt;/span&gt; &lt;span class="nt"&gt;--prefer-dist&lt;/span&gt; &lt;span class="nt"&gt;--optimize-autoloader&lt;/span&gt; &lt;span class="nt"&gt;--working-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/var/www/html/laravel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Setup MySQL Database with user input variables I stored in the external config file (remember). Set file permissions for Laravel storage and bootstrap cache directories. Setup the Laravel environment &lt;code&gt;.env&lt;/code&gt; file. Clear and cache Laravel Artisan configurations. Generate a Laravel key to ensure the security of user sessions and other encrypted data.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Setup MySQL Database&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Setting up MySQL database..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt;&lt;span class="nv"&gt;$DBPASS&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;MYSQL_SCRIPT&lt;/span&gt;&lt;span class="sh"&gt;
CREATE DATABASE &lt;/span&gt;&lt;span class="nv"&gt;$DBNAME&lt;/span&gt;&lt;span class="sh"&gt;;
CREATE USER '&lt;/span&gt;&lt;span class="nv"&gt;$DBUSER&lt;/span&gt;&lt;span class="sh"&gt;'@'localhost' IDENTIFIED BY '&lt;/span&gt;&lt;span class="nv"&gt;$DBPASS&lt;/span&gt;&lt;span class="sh"&gt;';
GRANT ALL PRIVILEGES ON &lt;/span&gt;&lt;span class="nv"&gt;$DBNAME&lt;/span&gt;&lt;span class="sh"&gt;.* TO '&lt;/span&gt;&lt;span class="nv"&gt;$DBUSER&lt;/span&gt;&lt;span class="sh"&gt;'@'localhost';
FLUSH PRIVILEGES;
&lt;/span&gt;&lt;span class="no"&gt;MYSQL_SCRIPT

&lt;/span&gt;&lt;span class="c"&gt;# Set permissions for Laravel storage and bootstrap cache directories&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Setting permissions for Laravel, storage and bootstrap cache directories..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; www-data:www-data /var/www/html/laravel
&lt;span class="nb"&gt;sudo chmod&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; 775 /var/www/html/laravel/storage /var/www/html/laravel/bootstrap/cache

&lt;span class="c"&gt;# Setup Laravel environment file&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Configuring Laravel environment..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo cp&lt;/span&gt; .env.example .env
&lt;span class="nb"&gt;sudo sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"s/DB_CONNECTION=sqlite/DB_CONNECTION=mysql/"&lt;/span&gt; .env
&lt;span class="nb"&gt;sudo sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s/^# DB_HOST=127.0.0.1/DB_HOST=127.0.0.1/'&lt;/span&gt; .env
&lt;span class="nb"&gt;sudo sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s/^# DB_PORT=3306/DB_PORT=3306/'&lt;/span&gt; .env
&lt;span class="nb"&gt;sudo sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"s/^# DB_DATABASE=laravel/DB_DATABASE=&lt;/span&gt;&lt;span class="nv"&gt;$DBNAME&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt; .env
&lt;span class="nb"&gt;sudo sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"s/^# DB_USERNAME=root/DB_USERNAME=&lt;/span&gt;&lt;span class="nv"&gt;$DBUSER&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt; .env
&lt;span class="nb"&gt;sudo sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"s/^# DB_PASSWORD=/DB_PASSWORD=&lt;/span&gt;&lt;span class="nv"&gt;$DBPASS&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt; .env
php artisan migrate

&lt;span class="c"&gt;# Clear and cache Laravel Artisan configurations&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Clearing and caching configurations..."&lt;/span&gt;
php artisan config:clear
php artisan cache:clear

&lt;span class="c"&gt;# Generate Laravel key&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Generating Laravel key..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;php artisan key:generate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now, the final piece is where I configure the Apache2 web server to serve the Laravel project through the web port 80. This means, when you input the IP address of the vm—which we set in the Vagrantfile (remember)—you’ll be able to see the display homepage of the Laravel app. Let’s take note of the display homepage of the Laravel app being the test to certify if our entire script ran correctly, because every other step taken in this script was made to arrive at this point.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Configure Apache to serve the Laravel project&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Configuring Apache to serve Laravel..."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apache2/sites-available/laravel.conf &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
&amp;lt;VirtualHost *:80&amp;gt;
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html/laravel/public
    &amp;lt;Directory /var/www/html/laravel/public&amp;gt;
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Require all granted
    &amp;lt;/Directory&amp;gt;
    ErrorLog &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;APACHE_LOG_DIR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;/error.log
    CustomLog &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;APACHE_LOG_DIR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;/access.log combined
&amp;lt;/VirtualHost&amp;gt;
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Enable the Laravel site&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;a2ensite laravel.conf
&lt;span class="nb"&gt;sudo &lt;/span&gt;a2dissite 000-default.conf
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart apache2

&lt;span class="c"&gt;# LAMP stack + Laravel deployment: success&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"LAMP stack and Laravel are installed."&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;###################################################"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Script executed successfully."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;After the script runs completely (on the master vm), if you input the IP address of the master vm (192.168.56.10) into a browser and hit enter, the browser will display the homepage of the Laravel app that was cloned from GitHub. This confirms that the script ran successfully and the Laravel app is accessible via the master vm.&lt;/li&gt;
&lt;/ul&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%2Fv460hzfcczny0poupytk.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%2Fv460hzfcczny0poupytk.png" title="Laravel App landing page display served from web server (Apache2) on Master VM through IP address 192.168.56.10" alt="Laravel App landing page display served from web server (Apache2) on Master VM through IP address 192.168.56.10" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ansible, and running the script in the Slave VM.
&lt;/h2&gt;

&lt;p&gt;Once the bash script runs successfully on the master vm the next step is to run the script in the slave vm, using Ansible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Ansible?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ansible is a tool used to manage and set up different computers and servers automatically, without needing to manually type commands or install software on each one individually. It works by letting you write simple instructions that tell your computers what software to install, what settings to use, and how to communicate with each other. This is especially helpful for people who need to handle many computers at once, as it makes the process much faster and reduces the chance of making mistakes.&lt;/p&gt;

&lt;p&gt;The simple instructions you write through Ansible to communicate with computers and servers are called Playbooks, also known as Ansible Playbooks. These Ansible Playbooks are data files written in YAML format.&lt;/p&gt;

&lt;p&gt;To run the bash script from the master vm on the slave vm, using Ansible, we need to write an Ansible Playbook.&lt;/p&gt;

&lt;p&gt;Here’s how I did that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, I created an Ansible Inventory file. Ansible reads this file to know and set the connection mechanism between the master vm and the slave vm. Ansible connects to servers through an SSH connection. For the SSH connection to work, Ansible needs to know the whereabouts (or directory) of the private key with which to connect to the slave vm, that’s what the line below does.
&lt;code&gt;ansible_ssh_private_key_file: /home/vagrant/.ssh/id_rsa_slavevm&lt;/code&gt;
Note: Ansible Inventory files similar to Ansible Playbooks are written YAML format.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;all&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;slave&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;ansible_host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;192.168.56.11&lt;/span&gt;
      &lt;span class="na"&gt;ansible_user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vagrant&lt;/span&gt;
      &lt;span class="na"&gt;ansible_ssh_private_key_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/vagrant/.ssh/id_rsa_slavevm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The Ansible Playbook, as seen in the code below, which is set to “Deploy LAMP stack/Laravel application and set cron job on Slave node” on the slave vm, runs 6 tasks which are ultimately supposed to facilitate 3 things: transfer the bash script from the master vm to the slave vm, execute the bash script on the slave vm, and set a cronjob to check and log server uptime on the slave vm every 12 am.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy LAMP stack/Laravel application and set cron job on Slave node&lt;/span&gt;
  &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;slave&lt;/span&gt;

  &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Transfer Master VM bash script to Slave node&lt;/span&gt;
      &lt;span class="na"&gt;copy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/vagrant/deploy-LAMP-stack.sh&lt;/span&gt;
        &lt;span class="na"&gt;dest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/vagrant/deploy-LAMP-stack.sh&lt;/span&gt;
        &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0755"&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Transfer Master VM config file to Slave node&lt;/span&gt;
      &lt;span class="na"&gt;copy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/vagrant/deploy-LAMP-stack.cfg&lt;/span&gt;
        &lt;span class="na"&gt;dest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/vagrant/deploy-LAMP-stack.cfg&lt;/span&gt;
        &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0755"&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Remove Windows line endings from bash script&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sed -i 's/\r$//' deploy-LAMP-stack.sh&lt;/span&gt;
      &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;chdir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/vagrant&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Execute Master VM bash script on Slave node&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./deploy-LAMP-stack.sh&lt;/span&gt;
      &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;chdir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/vagrant&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Check if the Laravel application is up and running&lt;/span&gt;
      &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://192.168.56.11&lt;/span&gt;
        &lt;span class="na"&gt;return_content&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
      &lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;webpage&lt;/span&gt;
      &lt;span class="na"&gt;until&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;webpage.status == &lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
      &lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set cron job to check server uptime&lt;/span&gt;
      &lt;span class="na"&gt;cron&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Check&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;uptime"&lt;/span&gt;
        &lt;span class="na"&gt;minute&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0"&lt;/span&gt;
        &lt;span class="na"&gt;hour&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0"&lt;/span&gt;
        &lt;span class="na"&gt;job&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;uptime&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;/var/log/uptime.log"&lt;/span&gt; 

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Transfer Bash Script from Master VM to Slave VM
&lt;/h3&gt;

&lt;p&gt;Even though Vagrant VM provisioning offers a ‘shared folder’ feature which should allow access to the bash script on the slave vm via this path &lt;code&gt;/vagrant/scripts/deploy-LAMP-stack.sh&lt;/code&gt; , because the assignment instructed me to execute the bash script created in the master vm in the slave vm, my first task in the Ansible Playbook was to transfer the bash script from the master vm to the slave vm.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Transfer Master VM bash script to Slave node&lt;/span&gt;
      &lt;span class="s"&gt;copy&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/vagrant/deploy-LAMP-stack.sh&lt;/span&gt;
        &lt;span class="na"&gt;dest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/vagrant/deploy-LAMP-stack.sh&lt;/span&gt;
        &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0755"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Transferring the bash script also meant transferring the config file which is needed to run the bash script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Transfer Master VM config file to Slave node&lt;/span&gt;
      &lt;span class="s"&gt;copy&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/vagrant/deploy-LAMP-stack.cfg&lt;/span&gt;
        &lt;span class="na"&gt;dest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/vagrant/deploy-LAMP-stack.cfg&lt;/span&gt;
        &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0755"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The bash script file was created and edited on my WindowsOS PC, therefore, when the file was copied into a LinuxOS machine it had a problem with ‘line endings’ which is a common Windows-Linux problem. To resolve that, I created another task to remove Windows line endings from the bash script file—essentially, changing the file line endings from CRLF to LF [which is suitable for the Linux File System (LFS)].&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Remove Windows line endings from bash script&lt;/span&gt;
      &lt;span class="s"&gt;command&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sed -i 's/\r$//' deploy-LAMP-stack.sh&lt;/span&gt;
      &lt;span class="s"&gt;args&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;chdir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/vagrant&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Execute Bash Script on Slave VM
&lt;/h3&gt;

&lt;p&gt;Now, the bash script is transferred and configured in the home directory of the vagrant user on slave vm. I wrote a task using the Ansible ‘command’ module to run the bash script file on the slave vm.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Execute Master VM bash script on Slave node&lt;/span&gt;
      &lt;span class="s"&gt;command&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./deploy-LAMP-stack.sh&lt;/span&gt;
      &lt;span class="s"&gt;args&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;chdir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/vagrant&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To check if the bash script ran successfully, and the Laravel application is up and running on the slave vm, I wrote a task using the Ansible ‘uri’ module to check the web status of the slave vm’s IP address 192.168.56.11 .&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Check if the Laravel application is up and running&lt;/span&gt;
      &lt;span class="s"&gt;uri&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://192.168.56.11&lt;/span&gt;
        &lt;span class="na"&gt;return_content&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
      &lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;webpage&lt;/span&gt;
      &lt;span class="na"&gt;until&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;webpage.status == &lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
      &lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Set a Cronjob to Check and Log Server Uptime on the Slave VM Every 12 AM
&lt;/h3&gt;

&lt;p&gt;I wrote a task using the Ansible ‘cron’ module to set a cronjob to check and log server uptime to the path &lt;code&gt;/var/log/uptime.log&lt;/code&gt; on the slave vm every 12am.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set cron job to check server uptime&lt;/span&gt;
      &lt;span class="s"&gt;cron&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Check&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;uptime"&lt;/span&gt;
        &lt;span class="na"&gt;minute&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0"&lt;/span&gt;
        &lt;span class="na"&gt;hour&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0"&lt;/span&gt;
        &lt;span class="na"&gt;job&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;uptime&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;/var/log/uptime.log"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If I’d decided to stop here I’d have already completed the tasks required by my bootcamp and finished my assignment, but I took it a step forward to automate every manual process and fine-tune my work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Provisioning for both VMs (Master and Slave)
&lt;/h2&gt;

&lt;p&gt;After creating the bash script, confirming it works, writing Ansible Playbook, executing the bash script and setting a cronjob on slave vm, I provisioned the master and slave vm to automate manual steps and things I did within each of the vms during the entire process of my work. I did this to ensure I reduced the number of manual steps it took to perform the entire process again.&lt;/p&gt;

&lt;p&gt;This is what my Vagrantfile finally looked like.&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="c1"&gt;# -*- mode: ruby -*-&lt;/span&gt;
&lt;span class="c1"&gt;# vi: set ft=ruby :&lt;/span&gt;

&lt;span class="no"&gt;Vagrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2"&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;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="c1"&gt;# configure general VM&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ubuntu/jammy64"&lt;/span&gt;

  &lt;span class="c1"&gt;# configure master vm&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt; &lt;span class="s2"&gt;"master"&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;master&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"master"&lt;/span&gt;
    &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"private_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="s2"&gt;"192.168.56.10"&lt;/span&gt;

    &lt;span class="c1"&gt;# provision master vm&lt;/span&gt;
    &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;inline: &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;SHELL&lt;/span&gt;&lt;span class="sh"&gt;

    # Provision LAMP stack bash script into user directory
    sudo -u vagrant cp /vagrant/assets/config/deploy-LAMP-stack.cfg /home/vagrant
    sudo -u vagrant cp /vagrant/scripts/deploy-LAMP-stack.sh /home/vagrant
    sudo -u vagrant chmod +x /home/vagrant/deploy-LAMP-stack.sh
    sudo -u vagrant sed -i 's/&lt;/span&gt;&lt;span class="se"&gt;\r&lt;/span&gt;&lt;span class="sh"&gt;$//' /home/vagrant/deploy-LAMP-stack.sh # remove Windows carriage returns (CR) - Ensure script runs on Linux VM

    # Install and configure Ansible
    sudo add-apt-repository --yes --update ppa:ansible/ansible
    sudo apt install ansible -y
    cd /etc/ansible/
    sudo mv ansible.cfg ansible.cfg_backup
    sudo ansible-config init --disabled -t all &amp;gt; ansible.cfg
    sudo sed -i "s/^;host_key_checking=True/host_key_checking=False/" /etc/ansible/ansible.cfg # Stop Ansible from interaction during ssh login - improve automation process

    # Provision Ansible files into user directory
    sudo -u vagrant cp -r /vagrant/scripts/ansible /home/vagrant
&lt;/span&gt;&lt;span class="no"&gt;    SHELL&lt;/span&gt;

    &lt;span class="c1"&gt;# provision master vm: Generate SSH key-pair&lt;/span&gt;
    &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;path: &lt;/span&gt;&lt;span class="s2"&gt;"scripts/ssh_keygen.sh"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# configure slave vm&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt; &lt;span class="s2"&gt;"slave"&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;slave&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;slave&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"slave"&lt;/span&gt;
    &lt;span class="n"&gt;slave&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"private_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="s2"&gt;"192.168.56.11"&lt;/span&gt;

    &lt;span class="c1"&gt;# provision slave vm&lt;/span&gt;
    &lt;span class="n"&gt;slave&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;inline: &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;SHELL&lt;/span&gt;&lt;span class="sh"&gt;

    # Secure SSH connection
    sudo sed -i "s/^#PermitRootLogin prohibit-password/PermitRootLogin prohibit-password/" /etc/ssh/sshd_config # Turn off password-enabled root ssh login
    sudo sed -i "s/^#PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config # Turn off password-enabled ssh login
    sudo systemctl restart ssh # Restart ssh service to enable config
&lt;/span&gt;&lt;span class="no"&gt;    SHELL&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt; 

  &lt;span class="c1"&gt;# provision both vms&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;inline: &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;SHELL&lt;/span&gt;&lt;span class="sh"&gt;

  # update system
  sudo apt-get update

  # Turn off restart of services - Change line 38 from "&lt;/span&gt;&lt;span class="si"&gt;#$nrconf&lt;/span&gt;&lt;span class="sh"&gt;{restart} = 'i';" to "&lt;/span&gt;&lt;span class="si"&gt;#$nrconf&lt;/span&gt;&lt;span class="sh"&gt;{restart} = 'a';"
  sudo apt-get install -y needrestart
  sudo sed -i "38s/#&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="sh"&gt;$nrconf{restart} = 'i';/#&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="sh"&gt;$nrconf{restart} = 'a';/" /etc/needrestart/needrestart.conf

  # Ensure SSH is installed &amp;amp; enabled
  sudo apt install openssh-server openssh-client -y
&lt;/span&gt;&lt;span class="no"&gt;  SHELL&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This Vagrantfile can be segmented into three parts. One, the config &amp;amp; provisioning of both vms. Two, the config and provisioning of the master vm. Three, the config &amp;amp; provisioning of the slave vm.&lt;/p&gt;

&lt;h3&gt;
  
  
  Config &amp;amp; Provisioning of both VMS (Master &amp;amp; Slave)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# provision both vms&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;inline: &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;SHELL&lt;/span&gt;&lt;span class="sh"&gt;

  # update system
  sudo apt-get update

  # Turn off restart of services - Change line 38 from "&lt;/span&gt;&lt;span class="si"&gt;#$nrconf&lt;/span&gt;&lt;span class="sh"&gt;{restart} = 'i';" to "&lt;/span&gt;&lt;span class="si"&gt;#$nrconf&lt;/span&gt;&lt;span class="sh"&gt;{restart} = 'a';"
  sudo apt-get install -y needrestart
  sudo sed -i "38s/#&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="sh"&gt;$nrconf{restart} = 'i';/#&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="sh"&gt;$nrconf{restart} = 'a';/" /etc/needrestart/needrestart.conf

  # Ensure SSH is installed &amp;amp; enabled
  sudo apt install openssh-server openssh-client -y
&lt;/span&gt;&lt;span class="no"&gt;  SHELL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Updated both vm app package repositories using this command
&lt;code&gt;sudo apt-get update&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Set ‘needrestart’ feature for scripts when they installed to ‘a’ which means automatically, instead of ‘i’ which means interactive.&lt;/li&gt;
&lt;li&gt;Installed SSH software package on both VMs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Config &amp;amp; Provisioning of Master VM
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# provision master vm&lt;/span&gt;
    &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;inline: &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;SHELL&lt;/span&gt;&lt;span class="sh"&gt;

    # Provision LAMP stack bash script into user directory
    sudo -u vagrant cp /vagrant/assets/config/deploy-LAMP-stack.cfg /home/vagrant
    sudo -u vagrant cp /vagrant/scripts/deploy-LAMP-stack.sh /home/vagrant
    sudo -u vagrant chmod +x /home/vagrant/deploy-LAMP-stack.sh
    sudo -u vagrant sed -i 's/&lt;/span&gt;&lt;span class="se"&gt;\r&lt;/span&gt;&lt;span class="sh"&gt;$//' /home/vagrant/deploy-LAMP-stack.sh # remove Windows carriage returns (CR) - Ensure script runs on Linux VM

    # Install and configure Ansible
    sudo add-apt-repository --yes --update ppa:ansible/ansible
    sudo apt install ansible -y
    cd /etc/ansible/
    sudo mv ansible.cfg ansible.cfg_backup
    sudo ansible-config init --disabled -t all &amp;gt; ansible.cfg
    sudo sed -i "s/^;host_key_checking=True/host_key_checking=False/" /etc/ansible/ansible.cfg # Stop Ansible from interaction during ssh login - improve automation process

    # Provision Ansible files into user directory
    sudo -u vagrant cp -r /vagrant/scripts/ansible /home/vagrant
&lt;/span&gt;&lt;span class="no"&gt;    SHELL&lt;/span&gt;

    &lt;span class="c1"&gt;# provision master vm: Generate SSH key-pair&lt;/span&gt;
    &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;path: &lt;/span&gt;&lt;span class="s2"&gt;"scripts/ssh_keygen.sh"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Copied the bash script and external config file from the Vagrant shared folder to the Vagrant user home directory, set file permissions, and changed the file line endings from CRLF to LF [which is suitable for the Linux File System (LFS)] using the &lt;code&gt;sed&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;Installed and configured Ansible:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sudo mv ansible.cfg ansible.cfg_backup&lt;/code&gt; backed up the initial Ansible config file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sudo ansible-config init --disabled -t all &amp;gt; ansible.cfg&lt;/code&gt; created a new Ansible config file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sudo sed -i "s/^;host_key_checking=True/host_key_checking=False/" /etc/ansible/ansible.cfg&lt;/code&gt; accessed Ansible config file and changed ‘host_key_checking’ variable from True to False. I did this so that Ansible doesn’t ask/prompt an interactive question when the Ansible Playbook is run. Because as a general rule of thumb, you do not want an automated script to prompt an interactive question, ensuring it runs noninteractively is the best way to certify that the script will run uninterrupted once set in motion.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Copied Ansible files (the inventory and playbook file) from the Vagrant shared folder to the Vagrant user home directory.&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;code&gt;master.vm.provision "shell", path: "scripts/ssh_keygen.sh"&lt;/code&gt; generated ssh key-pair for the master vm through a script called ‘ssh_keygen.sh’. We’ll need this ssh key-pair later to access the slave vm through the master vm.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;My provisioning code earlier instructed Vagrant to run script ‘ssh_keygen.sh’ on the master vm. This is what the script ‘ssh_keygen.sh’ looks like. Again, this script runs in such a way that is not interactive.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# Check for existing SSH keys and generate a new one if none exists&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"/home/vagrant/.ssh/id_rsa_slavevm"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Generating SSH key..."&lt;/span&gt;
  &lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; vagrant ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 4096 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"slave vm pka created by Allwell 220424"&lt;/span&gt; &lt;span class="nt"&gt;-N&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"/home/vagrant/.ssh/id_rsa_slavevm"&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"SSH key generated."&lt;/span&gt;
  &lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; vagrant &lt;span class="nb"&gt;chmod &lt;/span&gt;400 /home/vagrant/.ssh/id_rsa_slavevm
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"SSH key already exists."&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

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


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Config &amp;amp; Provisioning of Slave VM
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# provision slave vm&lt;/span&gt;
    &lt;span class="n"&gt;slave&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;inline: &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;SHELL&lt;/span&gt;&lt;span class="sh"&gt;

    # Secure SSH connection
    sudo sed -i "s/^#PermitRootLogin prohibit-password/PermitRootLogin prohibit-password/" /etc/ssh/sshd_config # Turn off password-enabled root ssh login
    sudo sed -i "s/^#PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config # Turn off password-enabled ssh login
    sudo systemctl restart ssh # Restart ssh service to enable config
&lt;/span&gt;&lt;span class="no"&gt;    SHELL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Secured the SSH server connection on the slave vm in anticipation of a connection from the master vm.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sudo sed -i "s/^#PermitRootLogin prohibit-password/PermitRootLogin prohibit-password/" /etc/ssh/sshd_config&lt;/code&gt; turned off password-enabled root ssh login into the slave vm.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sudo sed -i "s/^#PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config&lt;/code&gt; turned off password-enabled ssh login.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Restarted the SSH service or daemon to enable the new SSH configurations.&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  End of Setup
&lt;/h2&gt;

&lt;p&gt;Congratulations on getting to this point of my how-to guide. Finally, my code, provisioning, scripting, and automation is done. Everything works. I’m in awe. I’m elated. I just created something beautiful that runs.&lt;/p&gt;

&lt;p&gt;But don’t take my word that it runs, try it for yourself using the links and techniques I’ll share next: &lt;strong&gt;how to test that this entire setup works on your own PC&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  HOW TO TEST: Deploy LAMP stack through bash script built on Master VM on Slave VM using Ansible.
&lt;/h2&gt;

&lt;p&gt;I’ve published all my code to GitHub (&lt;a href="https://github.com/allwelldotdev/altschool-cloud-sem2-project_exam" rel="noopener noreferrer"&gt;https://github.com/allwelldotdev/altschool-cloud-sem2-project_exam&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Clone my repo and try this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites &amp;amp; Dependencies:&lt;/strong&gt; You’ll need to have the following software installed on your pc for these tests to work.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vagrant&lt;/li&gt;
&lt;li&gt;Oracle VM Virtualbox Manager&lt;/li&gt;
&lt;li&gt;Git Bash (for Windows users).&lt;/li&gt;
&lt;li&gt;Web browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Things To Do:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your Git Bash terminal (for Windows users) or Terminal (for MacOS users).&lt;/li&gt;
&lt;li&gt;Clone my GitHub repo, and change directory into my GitHub project.&lt;/li&gt;
&lt;li&gt;Apply the command &lt;code&gt;vagrant up &amp;amp;&amp;amp; vagrant ssh master&lt;/code&gt; to fire up both vms (master &amp;amp; slave) taking configurations and provisions instructions from my Vagrantfile.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At this point, let’s recall, in the title, I stated that I reduced to just 2 steps the deployment of a LAMP stack + Laravel app using Bash Shell Scripting, Vagrant, and Ansible.&lt;/p&gt;

&lt;p&gt;Here are the two steps:&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Copy the Master VM SSH Public Key into the Slave VM ‘authorized_keys’ file.
&lt;/h2&gt;

&lt;p&gt;After firing up both vms using the &lt;code&gt;vagrant up&lt;/code&gt; command, and logging into the master vm using &lt;code&gt;vagrant ssh master&lt;/code&gt; , next, we’ll copy the master vm ssh public key into the slave vm ‘authorized_keys’ file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Type in the following command into your terminal and hit enter.&lt;br&gt;
&lt;code&gt;cat ~/.ssh/id_rsa_slavevm.pub&lt;/code&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%2F2hucolx6j81qc42i62ax.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%2F2hucolx6j81qc42i62ax.png" alt="Screenshot 2024-04-25 211316.png" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select and copy the ssh public key ‘id_rsa_slavevm.pub’.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open another terminal window/process, type the command&lt;br&gt;
&lt;code&gt;vagrant ssh slave&lt;/code&gt; to bring up the slave vm, then type the following command into your terminal and hit enter.&lt;br&gt;
&lt;code&gt;vim ~/.ssh/authorized_keys&lt;/code&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%2Fp76am28dzijwnyrhmct9.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%2Fp76am28dzijwnyrhmct9.png" alt="Screenshot 2024-04-25 211604.png" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This will open a vim editor on your terminal. Type ‘o’ then paste the public key into the file by pressing ‘Shift + Ins’.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Close the vim editor by pressing, in this order, ‘Esc’, then ‘:wq’, hit enter. This should save your entry in the file and close the vim editor.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 2: Run the Ansible Playbook.
&lt;/h2&gt;

&lt;p&gt;Once you’ve completed Step 1, the next thing to do is run the Ansible Playbook. Remember, because of our master vm provisioning techniques we have already copied our Ansible Playbook and Inventory file from the Vagrant Shared Folder to our Vagrant user home directory on the master vm.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go back to the other terminal where you’d earlier logged into the master vm. Make sure your working directory is the home directory of the Vagrant user. You can confirm by using the command &lt;code&gt;pwd&lt;/code&gt; . It should return &lt;code&gt;/home/vagrant&lt;/code&gt; . If it doesn’t, use the command &lt;code&gt;cd /home/vagrant&lt;/code&gt; and follow on with the next bullet point.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;List the home directory, using the &lt;code&gt;ls&lt;/code&gt; command, and you should see the ‘ansible’ directory which was provisioned into the vm. Change directory into the ‘ansible’ directory. In the ‘ansible’ directory are two files: inv.yaml (Ansible Inventory file) and plyabook.yaml (Ansible Playbook file). We would use these files to run the Ansible Playbook.&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%2Fo2pg3qebfho9galrcd0p.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%2Fo2pg3qebfho9galrcd0p.png" alt="Screenshot 2024-04-25 211526.png" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the Ansible Playbook using this command:&lt;br&gt;
&lt;code&gt;ansible-playbook -i inv.yaml playbook.yaml&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  In Conclusion
&lt;/h2&gt;

&lt;p&gt;Once you run the Ansible Playbook, Ansible, through Python scripts, will execute all the tasks sets in the playbook on the slave vm.&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%2Fux5shzzfu70yfp16inmz.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%2Fux5shzzfu70yfp16inmz.png" alt="Screenshot 2024-04-25 213547" width="800" height="668"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will complete the assignment, and when you open the slave vm IP address (192.168.56.11) in a browser, you’ll access the landing page of the Laravel App served through the web server (Apache) on the slave vm.&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%2Fqvc34iaiv8k5pksk5psu.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%2Fqvc34iaiv8k5pksk5psu.png" title="Laravel App landing page display served from web server (Apache2) on Slave VM through IP address 192.168.56.11" alt="Laravel App landing page display served from web server (Apache2) on Slave VM through IP address 192.168.56.11" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s how you deploy a LAMP stack + Laravel App using Bash Shell Scripting, Vagrant, and Ansible with just 2 steps.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

&lt;p&gt;Stay healthy. Stay curious.&lt;/p&gt;




&lt;p&gt;PS. I’ve published this article on &lt;a href="https://www.linkedin.com/pulse/infrastructure-automation-i-reduced-just-2-steps-lamp-agwu-okoro-rrwsf/?trackingId=txZHdUfoQOqo%2BAA74MfP3w%3D%3D" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://medium.com/@allwelldotdev/infrastructure-automation-i-reduced-to-just-2-steps-the-deployment-of-a-lamp-stack-laravel-app-47f24a4e87fe" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;, and my &lt;a href="https://github.com/allwelldotdev/altschool-cloud-sem2-project_exam/blob/main/article.md" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. I’d like to ask you to, please give it a like and share so others may benefit from it too. Thank you.&lt;/p&gt;

</description>
      <category>cloudcomputing</category>
      <category>linux</category>
      <category>bash</category>
      <category>ansible</category>
    </item>
  </channel>
</rss>
